You may see job names like test-1, build-2, or lint-3-1 in the CircleCI UI and in GitHub status checks. This often happens even when:
Each workflow lists the job only once
Config validation does not report an unresolved duplicate job
Re-running a workflow does not change the extra numbers
This is expected 2.1 config compilation behavior. It is not caused by two workflows running at the same time, and it is not a duplicate-pipeline trigger.
Related (same job twice inside one workflow): How to Run the Same Job Twice in a Single Workflow
Why the suffix appears
CircleCI compiles reusable and parameterized jobs into a flattened config. Compiled job keys must be unique across the entire compiled file, not only inside one workflow.
If the same job is invoked more than once — in one workflow or across several — and those invocations expand to different definitions, the compiler cannot keep a single name. It appends counters (job-1, job-2). Nested counters such as job-3-1 are the same uniqueness logic applied more than once.
Invocations often differ because of any of the following:
Job parameters with different values
Different
filters,context,pre-steps, orpost-stepsOrb jobs that expand differently per call
If two invocations compile to the same definition, they can keep the original name. Identical use across workflows does not always get a suffix.
The numbers are assigned when the pipeline’s config is processed. Re-running a workflow in that pipeline reuses those names.
This is not:
Duplicate pipelines from the same git push
Workflows overlapping at runtime
A requirement that every job appear only once in the whole config file
How to confirm
Open an affected pipeline and view the processed configuration (pipeline Configuration in the UI), or run:
circleci config process .circleci/config.yml
Search the compiled
jobs:map for the original job name plus numbered variants (test,test-1,test-2).
Multiple compiled entries that came from one source job confirm compilation uniquified the names.
How to control the name
Unique name: on each invocation
Set name on the workflow job (not on the job definition under jobs:). The assigned names must be unique, or numbers are still appended.
workflows:
build:
jobs:
- sayhello:
name: build-sayhello
saywhat: Everyone
deploy:
jobs:
- sayhello:
name: deploy-sayhello
saywhat: All
See the name key and Reusable config.
Reusing the same name: (for example name: test on every test invocation) does not stop suffixes if those expansions still differ.
Keep one GitHub or UI name
If branch protection expects a check named test:
Give
name: testonly to the invocation that must match that check, and unique names to the others, orMake the invocations compile identically (same parameters, filters, context, and steps) so the compiler can keep one key.
GitHub required checks match the compiled job name CircleCI reports. A pending check named test while CircleCI ran test-1 is this naming behavior.
Workflow-level when instead of per-job filters
If several workflows exist only to pick a branch, unused workflows can still be compiled. Job-level filters on every job still produce extra expansions.
Moving branch logic to a workflow-level when: can omit those workflows from compilation so unused expansions never exist. Use this when you want the original job name without unique aliases.