Skip to content

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

Description

@benipal95

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:

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

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:

export PROJECT_ID=<id from above>

Step 2 — Create a Databricks credential on that project

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:

export CRED_ID=<id from above>

Step 3 — DELETE the credential (this fails)

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.

Actual Result

< HTTP/2 400
{
  "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:

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions