Skip to content

fix: reject identifier keys containing special characters#200

Merged
b-per merged 1 commit into
mainfrom
fix/validate-identifier-special-chars
Mar 24, 2026
Merged

fix: reject identifier keys containing special characters#200
b-per merged 1 commit into
mainfrom
fix/validate-identifier-special-chars

Conversation

@b-per
Copy link
Copy Markdown
Collaborator

@b-per b-per commented Mar 24, 2026

Summary

  • Adds VALID_IDENTIFIER_RE = re.compile(r"^[a-zA-Z0-9_-]+$") to schemas/job.py as the single source of truth for what characters are valid in a job identifier
  • Updates _validate_job_identifiers in the loader to use it, replacing the spaces-only check
  • Raises a clear LoadingJobsYAMLError at load time instead of silently failing during the dbt Cloud round-trip

Root cause (Closes #199)

Identifiers are embedded in job names as [[identifier]] and extracted via regex when fetching from dbt Cloud. The extraction regex only allows [a-zA-Z0-9_-] — any other character (e.g. &) causes extraction to return None, making the job invisible to the matching logic. On every subsequent run the tool treats the job as new and creates a duplicate.

The previous validator only rejected spaces; characters like &, @, . passed through silently.

The regex used to extract identifiers from dbt Cloud job names only
allows [a-zA-Z0-9_-]. Characters like & would silently cause extraction
to return None, making every run treat those jobs as new and create
duplicates.

Add VALID_IDENTIFIER_RE to schemas/job.py as a single source of truth
and update _validate_job_identifiers in the loader to enforce it,
raising a clear LoadingJobsYAMLError instead of failing silently later.

Closes #199
@github-actions
Copy link
Copy Markdown
Contributor

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/dbt_jobs_as_code
   main.py31016048%120–123, 129, 168–169, 200–203, 209, 245–329, 400–405, 418–419, 437–438, 442–444, 461–510, 539–597, 628–673, 678–679, 683
src/dbt_jobs_as_code/client
   __init__.py1794674%16, 53–54, 62, 99–100, 119–120, 139–140, 155–156, 170–171, 187–188, 205, 215, 295–310, 333, 349–350, 360–372, 375–386, 391–400
src/dbt_jobs_as_code/cloud_yaml_mapping
   change_set.py2353087%27–29, 59, 65–66, 155, 212, 224, 247, 251–252, 258–260, 275–278, 334–348, 401–423, 459–473
src/dbt_jobs_as_code/importer
   __init__.py27774%14–15, 22–27
src/dbt_jobs_as_code/schemas
   __init__.py23291%68, 78
   common_types.py60395%67–68, 91
   config.py14193%18
   job.py132695%237, 242, 258–267
TOTAL118325578% 

Tests Skipped Failures Errors Time
167 0 💤 0 ❌ 0 🔥 13.170s ⏱️

@b-per
Copy link
Copy Markdown
Collaborator Author

b-per commented Mar 24, 2026

CI passed

@b-per b-per merged commit 3121917 into main Mar 24, 2026
9 checks passed
@b-per b-per deleted the fix/validate-identifier-special-chars branch March 24, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Duplicated jobs

1 participant