Skip to content

The camel-case-properties rule appears flaky #768

@LasseHels

Description

@LasseHels

Hey there!

First of all: thanks for making this awesome tool.

I am having a bit of an issue with the camel-case-properties rule. Our specification follows the camelCase convention, but we have a couple fields that must be snake_case because of a downstream constraint.

One of the field causes the linter to consistently fail. I added this to vacuum's ignore file which solved the issue:

camel-case-properties:
  - $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

However, it seems one of the other fields causes vacuum to rarely fail:

➜  redacted git:(main) make lint-openapi
vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

 ██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗ 《《《─═─═── ·* · ˙*
 ██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║《《《──═─═──· ··* ˙˙
 ██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║《《《───═─═─··· ˙˙ ˙
 ╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║《《──═─═──·* ·· ˙˙
  ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ 《《─═─═──* · · ˙
   ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝ 《───═─═─· ··* ˙˙ ˙

 version: 0.20.5 | compiled: Thu, 11 Dec 2025 00:15:56 UTC
 https://quobix.com/vacuum/ | https://github.com/daveshanley/vacuum

 Using ignore file 'redacted/vacuum-ignore.yml'
 ignored items:
 └─ camel-case-properties: $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

 using ruleset 'vacuum-ruleset.yml' (containing 50 rules)
 vacuuming file './api/openapi.yml' against 50 rules: https://quobix.com/vacuum/rulesets/recommended

 --> use the <dashboard> command to be able to navigate results interactively <--

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                         │
│  Quality Score: 100/100 [A+]                                                                            │
│                                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 │
 │ ✓ A perfect score! Like Mary Poppins, practically perfect in every way. Incredible, well done!
 │

 use --debug if you want to enable developer logging

➜  redacted git:(main) make lint-openapi
vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

 ██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗ 《《《─═─═── ·* · ˙*
 ██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║《《《──═─═──· ··* ˙˙
 ██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║《《《───═─═─··· ˙˙ ˙
 ╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║《《──═─═──·* ·· ˙˙
  ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ 《《─═─═──* · · ˙
   ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝ 《───═─═─· ··* ˙˙ ˙

 version: 0.20.5 | compiled: Thu, 11 Dec 2025 00:15:56 UTC
 https://quobix.com/vacuum/ | https://github.com/daveshanley/vacuum

 Using ignore file 'redacted/vacuum-ignore.yml'
 ignored items:
 └─ camel-case-properties: $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

 using ruleset 'vacuum-ruleset.yml' (containing 50 rules)
 vacuuming file './api/openapi.yml' against 50 rules: https://quobix.com/vacuum/rulesets/recommended

 --> use the <dashboard> command to be able to navigate results interactively <--

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                         │
│  Quality Score: 100/100 [A+]                                                                            │
│                                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 │
 │ ✓ A perfect score! Like Mary Poppins, practically perfect in every way. Incredible, well done!
 │

 use --debug if you want to enable developer logging

➜  redacted git:(main) make lint-openapi
vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

 ██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗ 《《《─═─═── ·* · ˙*
 ██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║《《《──═─═──· ··* ˙˙
 ██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║《《《───═─═─··· ˙˙ ˙
 ╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║《《──═─═──·* ·· ˙˙
  ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ 《《─═─═──* · · ˙
   ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝ 《───═─═─· ··* ˙˙ ˙

 version: 0.20.5 | compiled: Thu, 11 Dec 2025 00:15:56 UTC
 https://quobix.com/vacuum/ | https://github.com/daveshanley/vacuum

 Using ignore file 'redacted/vacuum-ignore.yml'
 ignored items:
 └─ camel-case-properties: $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

 using ruleset 'vacuum-ruleset.yml' (containing 50 rules)
 vacuuming file './api/openapi.yml' against 50 rules: https://quobix.com/vacuum/rulesets/recommended

 --> use the <dashboard> command to be able to navigate results interactively <--

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                         │
│  Quality Score: 100/100 [A+]                                                                            │
│                                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 │
 │ ✓ A perfect score! Like Mary Poppins, practically perfect in every way. Incredible, well done!
 │

 use --debug if you want to enable developer logging

➜  redacted git:(main) make lint-openapi
vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

 ██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗ 《《《─═─═── ·* · ˙*
 ██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║《《《──═─═──· ··* ˙˙
 ██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║《《《───═─═─··· ˙˙ ˙
 ╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║《《──═─═──·* ·· ˙˙
  ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ 《《─═─═──* · · ˙
   ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝ 《───═─═─· ··* ˙˙ ˙

 version: 0.20.5 | compiled: Thu, 11 Dec 2025 00:15:56 UTC
 https://quobix.com/vacuum/ | https://github.com/daveshanley/vacuum

 Using ignore file 'redacted/vacuum-ignore.yml'
 ignored items:
 └─ camel-case-properties: $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

 using ruleset 'vacuum-ruleset.yml' (containing 50 rules)
 vacuuming file './api/openapi.yml' against 50 rules: https://quobix.com/vacuum/rulesets/recommended

 --> use the <dashboard> command to be able to navigate results interactively <--

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                         │
│  Quality Score: 100/100 [A+]                                                                            │
│                                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 │
 │ ✓ A perfect score! Like Mary Poppins, practically perfect in every way. Incredible, well done!
 │

 use --debug if you want to enable developer logging

➜  redacted git:(main) make lint-openapi
vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

 ██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗ 《《《─═─═── ·* · ˙*
 ██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║《《《──═─═──· ··* ˙˙
 ██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║《《《───═─═─··· ˙˙ ˙
 ╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║《《──═─═──·* ·· ˙˙
  ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ 《《─═─═──* · · ˙
   ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝ 《───═─═─· ··* ˙˙ ˙

 version: 0.20.5 | compiled: Thu, 11 Dec 2025 00:15:56 UTC
 https://quobix.com/vacuum/ | https://github.com/daveshanley/vacuum

 Using ignore file 'redacted/vacuum-ignore.yml'
 ignored items:
 └─ camel-case-properties: $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

 using ruleset 'vacuum-ruleset.yml' (containing 50 rules)
 vacuuming file './api/openapi.yml' against 50 rules: https://quobix.com/vacuum/rulesets/recommended

 --> use the <dashboard> command to be able to navigate results interactively <--

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                         │
│  Quality Score: 100/100 [A+]                                                                            │
│                                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 │
 │ ✓ A perfect score! Like Mary Poppins, practically perfect in every way. Incredible, well done!
 │

 use --debug if you want to enable developer logging

➜  redacted git:(main) make lint-openapi
vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

 ██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗ 《《《─═─═── ·* · ˙*
 ██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║《《《──═─═──· ··* ˙˙
 ██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║《《《───═─═─··· ˙˙ ˙
 ╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║《《──═─═──·* ·· ˙˙
  ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ 《《─═─═──* · · ˙
   ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝ 《───═─═─· ··* ˙˙ ˙

 version: 0.20.5 | compiled: Thu, 11 Dec 2025 00:15:56 UTC
 https://quobix.com/vacuum/ | https://github.com/daveshanley/vacuum

 Using ignore file 'redacted/vacuum-ignore.yml'
 ignored items:
 └─ camel-case-properties: $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

 using ruleset 'vacuum-ruleset.yml' (containing 50 rules)
 vacuuming file './api/openapi.yml' against 50 rules: https://quobix.com/vacuum/rulesets/recommended

 --> use the <dashboard> command to be able to navigate results interactively <--

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                         │
│  Quality Score: 100/100 [A+]                                                                            │
│                                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 │
 │ ✓ A perfect score! Like Mary Poppins, practically perfect in every way. Incredible, well done!
 │

 use --debug if you want to enable developer logging

➜  redacted git:(main) make lint-openapi
vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

 ██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗ 《《《─═─═── ·* · ˙*
 ██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║《《《──═─═──· ··* ˙˙
 ██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║《《《───═─═─··· ˙˙ ˙
 ╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║《《──═─═──·* ·· ˙˙
  ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ 《《─═─═──* · · ˙
   ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝ 《───═─═─· ··* ˙˙ ˙

 version: 0.20.5 | compiled: Thu, 11 Dec 2025 00:15:56 UTC
 https://quobix.com/vacuum/ | https://github.com/daveshanley/vacuum

 Using ignore file 'redacted/vacuum-ignore.yml'
 ignored items:
 └─ camel-case-properties: $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

 using ruleset 'vacuum-ruleset.yml' (containing 50 rules)
 vacuuming file './api/openapi.yml' against 50 rules: https://quobix.com/vacuum/rulesets/recommended

 --> use the <dashboard> command to be able to navigate results interactively <--

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                         │
│  Quality Score: 100/100 [A+]                                                                            │
│                                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 │
 │ ✓ A perfect score! Like Mary Poppins, practically perfect in every way. Incredible, well done!
 │

 use --debug if you want to enable developer logging

➜  redacted git:(main) make lint-openapi
vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

 ██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗ 《《《─═─═── ·* · ˙*
 ██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║《《《──═─═──· ··* ˙˙
 ██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║《《《───═─═─··· ˙˙ ˙
 ╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║《《──═─═──·* ·· ˙˙
  ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ 《《─═─═──* · · ˙
   ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝ 《───═─═─· ··* ˙˙ ˙

 version: 0.20.5 | compiled: Thu, 11 Dec 2025 00:15:56 UTC
 https://quobix.com/vacuum/ | https://github.com/daveshanley/vacuum

 Using ignore file 'redacted/vacuum-ignore.yml'
 ignored items:
 └─ camel-case-properties: $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

 using ruleset 'vacuum-ruleset.yml' (containing 50 rules)
 vacuuming file './api/openapi.yml' against 50 rules: https://quobix.com/vacuum/rulesets/recommended


 > api/openapi.yml
 ----------------------------------------------------------------------------------------------------------

api/openapi.yml:983:13  ▲     property `hedwig_scope` is `snake_case` not `camelCase`
$.components.schemas['ServiceLevelObjectiveAlertV1'].properties['ticket'].allOf[0][0].properties['labels'].properties['hedwig_scope']
rule: camel-case-properties  category: Schemas


 category              ✗ errors      ▲ warnings    ● info
 ────────────────────  ────────────  ────────────  ────────────────────────────────────────────────────────
 Schemas               0             1             0
 ────────────────────  ────────────  ────────────  ────────────────────────────────────────────────────────
 total                 0             1             0

 rule                                      violations    quality impact
 ────────────────────────────────────────  ────────────  ──────────────────────────────────────────────────
 camel-case-properties                     1             ██████████████████████████████████████████████████
 ────────────────────────────────────────  ────────────  ──────────────────────────────────────────────────
 total                                     1

 --> use the <dashboard> command to be able to navigate results interactively <--

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                         │
│  Quality Score: 99/100 [A+]                                                                             │
│                                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 │
 │ ▲ Passed, but with 1 warnings and 0 informs.
 │

 use --debug if you want to enable developer logging

make: *** [lint-openapi] Error 1
➜  redacted git:(main) make lint-openapi
vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

 ██╗   ██╗ █████╗  ██████╗██╗   ██╗██╗   ██╗███╗   ███╗ 《《《─═─═── ·* · ˙*
 ██║   ██║██╔══██╗██╔════╝██║   ██║██║   ██║████╗ ████║《《《──═─═──· ··* ˙˙
 ██║   ██║███████║██║     ██║   ██║██║   ██║██╔████╔██║《《《───═─═─··· ˙˙ ˙
 ╚██╗ ██╔╝██╔══██║██║     ██║   ██║██║   ██║██║╚██╔╝██║《《──═─═──·* ·· ˙˙
  ╚████╔╝ ██║  ██║╚██████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║ 《《─═─═──* · · ˙
   ╚═══╝  ╚═╝  ╚═╝ ╚═════╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝ 《───═─═─· ··* ˙˙ ˙

 version: 0.20.5 | compiled: Thu, 11 Dec 2025 00:15:56 UTC
 https://quobix.com/vacuum/ | https://github.com/daveshanley/vacuum

 Using ignore file 'redacted/vacuum-ignore.yml'
 ignored items:
 └─ camel-case-properties: $.components.schemas['ServiceLevelObjectiveAlertSeverityV1'].properties['labels'].properties['hedwig_scope']

 using ruleset 'vacuum-ruleset.yml' (containing 50 rules)
 vacuuming file './api/openapi.yml' against 50 rules: https://quobix.com/vacuum/rulesets/recommended

 --> use the <dashboard> command to be able to navigate results interactively <--

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                         │
│  Quality Score: 100/100 [A+]                                                                            │
│                                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 │
 │ ✓ A perfect score! Like Mary Poppins, practically perfect in every way. Incredible, well done!
 │

 use --debug if you want to enable developer logging

make lint-openapi is this command:

vacuum lint -r vacuum-ruleset.yml ./api/openapi.yml --fail-severity=info --details --ignore-file=vacuum-ignore.yml --no-clip

This is the vacuum-ruleset.yml file:

---
extends:
  - [spectral:oas, recommended]
rules:
  oas3-missing-example: false
  component-description: false
  operation-description: false
  no-unnecessary-combinator: false

It is curious to me that the field in the ignore file causes vacuum to consistently fail, but that the other field does not have the same effect. I can't share our entire OpenAPI specification, but I may be able to share parts of it if there's something you need to know about it in order to debug.

I realise I can update my ignore file with the field that rarely fails, but I am curious to understand why it rarely fails. My expecation would be that it either always fails or always succeeds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions