dbt-labs / dbt-labs/dbt-cloud-openapi-spec

DELETE /v3/.../credentials/{id}/ returns HTTP 400

Open
#81 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
12
Forks
10
PR merge metrics
No merged PRs in 30d

Description

## Summary

The dbt Cloud v3 API `DELETE` endpoint for credentials returns HTTP 400 because the server deserializes the **stored** credential record and validates it against `DatabricksCredentialsSchema` (which has `additionalProperties: false`). The `token` and `schema` fields — which were accepted by the **create** endpoint via `credential_details` — are rejected as unexpected top-level properties during deletion.

**No request body is sent.** This is a server-side validation bug where the API's own stored data fails its own schema check on the delete path.

## Environment

| Field | Value |
|-------|-------|
| dbt Cloud host | `https://zt753.us1.dbt.com` (trial account) |
| API version | v3 |
| Adapter | Databricks (`databricks_v0`) |
| Date reproduced | 2026-04-24 |

## Steps to Reproduce

Set up your environment variables:

```bash
export DBT_HOST="https://zt753.us1.dbt.com" # your dbt Cloud host
export DBT_ACCT="123456789" # your account ID
export DBT_TOKEN="your-service-token"
```

### Step 1 — Create a project

```bash
curl -s -X POST "$DBT_HOST/api/v3/accounts/$DBT_ACCT/projects/" \
-H "Authorization: Token $DBT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "bug_repro_cred_delete", "dbt_project_subdirectory": "/"}'
```

Save the project ID:

```bash
export PROJECT_ID=
```

### Step 2 — Create a Databricks credential on that project

```bash
curl -s -X POST \
"$DBT_HOST/api/v3/accounts/$DBT_ACCT/projects/$PROJECT_ID/credentials/" \
-H "Authorization: Token $DBT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"account_id": '"$DBT_ACCT"',
"project_id": '"$PROJECT_ID"',
"type": "adapter",
"state": 1,
"threads": 4,
"target_name": "default",
"adapter_version": "databricks_v0",
"credential_details": {
"token": "dapi_fake_for_repro",
"schema": "my_schema"
}
}'
```

Save the credential ID:

```bash
export CRED_ID=
```

### Step 3 — DELETE the credential (this fails)

```bash
curl -sv -X DELETE \
"$DBT_HOST/api/v3/accounts/$DBT_ACCT/projects/$PROJECT_ID/credentials/$CRED_ID/" \
-H "Authorization: Token $DBT_TOKEN"
```

## Expected Result

```
< HTTP/2 204
```

No response body, as documented in the [dbt Cloud v3 API reference](https://docs.getdbt.com/dbt-cloud/api-v3#/operations/Delete%20Credentials).

## Actual Result

```
< HTTP/2 400
```

```json
{
"status": {
"code": 400,
"is_success": false,
"user_message": "The request was invalid. Please double check the provided data and try again.",
"developer_message": "Additional properties are not allowed ('schema', 'token' were unexpected)\n\nFailed validating 'additionalProperties' in schema: ..."
},
"data": "Additional properties are not allowed ('schema', 'token' were unexpected)"
}
```

The full `developer_message` shows the server loading the stored credential record and validating it against `DatabricksCredentialsSchema`, which has `additionalProperties: false`. The `token` and `schema` fields — stored via the `credential_details` wrapper during creation — are surfaced as top-level properties during the internal deserialization step and rejected.

## Key Observations

1. **No request body is sent** — this is a pure `DELETE` with no payload.
2. The same error occurs with both `Authorization: Token ...` and `Authorization: Bearer ...`.
3. The v2 endpoint (`/api/v2/accounts/{id}/credentials/{cred_id}/`) returns 404 — credentials created via v3 are not accessible via v2.
4. The error is adapter-specific. The `DatabricksCredentialFields` schema defines `token` and `schema` as known fields, but the outer `DatabricksCredentialsSchema` has `additionalProperties: false` and these fields appear to be "flattened" from `credential_details` into the top-level object during internal deserialization, causing the validation failure.
5. **This affects all Databricks credentials** — every credential created with the `databricks_v0` adapter via the v3 API will fail to delete.

## Workaround

Deleting the **parent project** cascade-deletes all its credentials:

```bash
curl -s -X DELETE \
"$DBT_HOST/api/v3/accounts/$DBT_ACCT/projects/$PROJECT_ID/" \
-H "Authorization: Token $DBT_TOKEN"
```

This works, but prevents targeted credential cleanup without destroying the entire project.

## Cleanup

If you ran the repro steps, delete the test project:

```bash
curl -s -X DELETE \
"$DBT_HOST/api/v3/accounts/$DBT_ACCT/projects/$PROJECT_ID/" \
-H "Authorization: Token $DBT_TOKEN"
```

## Impact

Any automation that provisions and tears down dbt Cloud Databricks credentials via the v3 API cannot cleanly delete individual credentials. The only workaround is to delete the entire project, which is destructive and prevents granular resource management.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.