# Rudder CLI FAQ


> Answers to frequently asked questions about Rudder CLI.



## Project files

#### Can I put multiple specs in one YAML file? {#multiple-specs-in-one-file}

No. Rudder CLI reads only the first YAML document in each file and ignores any documents after a `---` separator, without an error or warning. `apply` doesn't create the resources they define, and if those resources are already CLI-managed, it plans to delete them.

Put each spec in its own YAML file. See [Recommended Project Directory Structure](https://www.rudderstack.com/docs/rudder-cli/directory-structure/) for how to organize them.

#### Can I apply only part of a project? {#apply-part-of-project}

No. `apply` compares the specs under the `-l` path with every CLI-managed resource in the workspace. If `-l` points at a subdirectory or a single file, `apply` plans to delete every CLI-managed resource outside it.

Run `apply` on the project root, and check **Removed resources** in `apply --dry-run` before you apply. See [One project per workspace](https://www.rudderstack.com/docs/rudder-cli/import-resources/#one-project-per-workspace).

## Variables

#### Why does a variable's value change after substitution? {#variable-value-changed}

Rudder CLI pastes each value into the YAML text before it parses the file, so some characters in the value change how the YAML reads:

- **No quotes** (`key: {{ .VAR }}`): A space followed by `#` starts a comment, so the rest of the line is dropped. A line break can add keys, and values such as `true`, `123`, or `null` are no longer strings.
- **Double quotes** (`key: "{{ .VAR }}"`): A `\` starts an escape sequence, so `\t` becomes a tab, and a `"` ends the string early.

Wrap the reference in single quotes, as `import workspace` does:

```yaml
password: '{{ .DB_PASSWORD }}'
```

If the value contains a single quote, double it in the var file:

```yaml
DB_PASSWORD: "it''s-a-secret"
```

Multi-line values, such as private keys, keep their line breaks inside either kind of quotes, but only when the reference is the whole quoted value, as in `key: '{{ .VAR }}'`. Inside a longer quoted string, the line breaks become spaces. See [How to Use Variable Substitution in Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/variable-substitution/).

## Apply

#### My `apply` in CI did nothing and exited successfully. Why? {#apply-did-nothing-in-ci}

`apply` asks you to confirm the plan before it changes anything. When its output isn't a terminal, for example in a CI job or when you pipe it to another command or a file, it can't prompt, so it stops without applying anything and still exits with code 0. Pass `--confirm=false`:

```bash
rudder-cli apply -l <project-directory> --confirm=false
```

`destroy` behaves the same way. See [`apply`](https://www.rudderstack.com/docs/rudder-cli/commands/#apply).

#### What happens if I change a resource's `id`? {#change-resource-id}

Once a resource is CLI-managed, that is, after `apply` has created or imported it, `apply` treats a new `id` as a different resource: it deletes the old resource and creates a new one with a new remote ID. A recreated source also gets a new write key.

The delete runs even if the create fails. For example, if you change an account's `id`, the create fails because the old account still has the same name, and the old account is deleted anyway.

To rename a resource, change its name and keep its `id`. Before the first `apply` of an imported resource, you can still change its `id` safely if you update the matching `urn` in `metadata.import` too. See [IDs, metadata, and the dashboard](https://www.rudderstack.com/docs/rudder-cli/import-resources/#ids-metadata-and-the-dashboard).

## Dashboard changes

#### I deleted an imported resource in the dashboard. Why does `apply` keep failing? {#deleted-imported-resource}

`apply` links imported YAML to workspace resources through the remote IDs in `metadata.import`. If you delete a resource in the dashboard or through the API, `apply` keeps trying to link its deleted ID and fails on every run:

```text
x Import event-stream-connection:web-to-webhook
Error: ... http status code: 400, error: 'connection not found'
```

The message depends on the resource type, for example `Account with ID ... not found`, `Object Not Found`, `Resource Not Found.`, `Destination does not exist with given id`, or `event stream source with ID ... not found`. If several resources fail, `apply` prints only the first error.

`apply --dry-run` doesn't catch this, because it still lists the resource under **Importable resources**. It also happens after a successful `apply`, because the import metadata stays in the YAML.

To fix it, delete the resource's entry from `metadata.import`:

```yaml
metadata:
  import:
    workspaces:
      - workspace_id: "<workspace ID>"
        resources:
          - urn: "destination:my-webhook"   # delete this entry
            remote_id: "<remote ID>"
```

Then do one of the following:

- **Recreate the resource**: Keep its spec. `apply` creates it with a new ID, so a recreated source also gets a new write key.
- **Drop the resource**: Delete its spec too, and update any specs that reference it.

Run `apply --dry-run` to confirm the resource now appears under **New resources**, or not at all, then run `apply`.

**Warning:** Don&#39;t delete the whole `imported/` directory instead. A failed `apply` may have already linked the other imported resources, and removing their YAML makes the next `apply` delete them from the workspace.

#### I recreated a resource in the dashboard. Why does `apply` fail with "name already exists"? {#name-already-exists}

Resource names must be unique in a workspace, and `apply` checks only the resources it manages. If someone deletes a CLI-managed resource in the dashboard and creates a new one with the same name, the next `apply` tries to recreate the deleted resource, and the name is already taken:

```text
Error: ... http status code: 400, error code: '', error: 'A destination with the name already exists'
```

Other resource types print similar messages, such as `Source with name already exists`. For a resource you imported, see [I deleted an imported resource in the dashboard](#deleted-imported-resource) instead.

Fix it in one of two ways:

- **Keep the CLI version**: Delete or rename the dashboard copy, then run `apply`.
- **Keep the dashboard copy**: Delete the resource's spec and update any specs that reference it, so `apply --dry-run` shows no changes. Then run `import workspace` to bring the dashboard copy under Rudder CLI. See [How to Import Workspace Resources into Your Rudder CLI Project](https://www.rudderstack.com/docs/rudder-cli/import-resources/).

## Connections

#### Can I disable an Event Stream connection? {#disable-event-stream-connection}

No. Event Stream connections can't be disabled, so `validate` rejects `enabled: false` on them:

```text
'enabled' cannot be false: event stream connections cannot be disabled
```

Leave `enabled` out or set it to `true`. To stop delivery, delete the connection from the project. `apply` removes the connection and leaves the source and destination in place.

Only Reverse ETL connections support `enabled: false`. See [Manage Reverse ETL Connections using Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/retl-connections/).
