Skip to content

Build1 publisher3 min readPublished

ConfigDirector rejects a schema tightening while staging still holds a value that would fail

Remote config edits skip CI entirely, so the case for validating values where they are saved is easy. The check worth copying refuses a new JSON schema while any environment still holds a value it would reject.

The Engineer · Build desk

Illustration accompanying ConfigDirector rejects a schema tightening while staging still holds a value that would fail

What happened

  • A deploy passes a CI pipeline with test suites, static analysis and functional tests, while a remote config change passes a text box on a dashboard, according to the post.
  • The post's list of typical config outages covers a timeout entered in seconds where the code reads milliseconds, a URL pasted without its scheme, a JSON field missing, and 10 typed where 0.1 was expected.
  • Most services store a value as a boolean, string, number or JSON, which is enough to render the right input field and not enough to judge whether the value makes sense where it is used.
  • ConfigDirector gives each config a fine-grained type, so an Integer can be bounded 10 through 100, a URL type can require HTTPS, and a JSON config can carry a draft-07 schema.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • capability Enforcing constraints at the save path covers writers nobody planned for, including an assistant driving the API over MCP from a task description it cannot check against the calling code.
  • cost Each bound now exists twice, in the application and in the config type, and the two have to move together; a ceiling raised in code but not in the service turns a legitimate value into a failed save.
  • decision Teams adopting typed JSON configs have to sequence migrations, cleaning up every environment's stored value before narrowing the schema, because the tightening is what gets refused.

A minimum bound is what catches someone entering seconds where the code reads milliseconds. The post's worked example is a `search-page-size` config bounded 10 through 100, which cannot be saved as 0 or as 10000 [7]. Apply the same shape to a timeout. A slip from 1000 milliseconds to 1 is off by a factor of a thousand [2]. A minimum of 1000 refuses it; a minimum of 0 takes it. The maximum has the matching weakness in the other direction: `free-shipping-threshold` bounded 0 through 500 refuses a negative number and refuses ten times fifty [7], but an intended 45 typed as 450 saves cleanly, because 450 sits under the ceiling [3].

Rollout fractions are the easy case, because the two candidate numbers are far apart. A 10 in a field that expected 0.1 is a hundredfold error [1], and a Float with a maximum of 1 has nowhere to put it [4].

A bound narrows which wrong numbers can be saved. A typed input can delete the question. The post's Timespan type puts the unit in the input field rather than in a comment nobody reads [8].

The JSON handling is the part I would steal. A JSON config can carry a draft-07 schema, and every value the config could return is checked before it is saved: the default targeting rule value, every conditional rule value, the percentage rollout value, every experiment variation, in every environment [10]. The second check runs the other way. Update the schema and every existing value in every environment is tested against it, with the schema change rejected if any environment holds a value that would no longer pass [11]. The rejection lands on whoever narrows the contract before cleaning up staging.

On placement, the post is blunt: "A check that only runs in the dashboard is a suggestion", and it lists the other writers as the API, Terraform, "a script someone wrote in an afternoon", and AI coding assistants through an MCP server [12]. Constraints in ConfigDirector are enforced at save time, in every environment, through all interfaces, before anything reaches an SDK [9]. An assistant creating a flag or updating a rollout is working from a description of the task [14].

The adoption cost is a second home for every constant. The expectations the post enumerates, a positive integer timeout under thirty seconds, an HTTPS endpoint, a theme that is one of `light`, `dark` or `system`, a JSON payload with a `version` field and at most twenty items, currently live in the application and not in the flag service [5]. Move them into the config type and they are enforced at save [9]. Raise the code's timeout ceiling to sixty seconds without editing the type, and the legitimate value fails to save.

Booleans are outside all of this. The post says flags and kill switches do not need complicated validation at save time, and need monitoring and alerting for unexpected evaluation behaviour instead [13]. That is the most routine change a flag service handles. The post includes no incident data, and its account of how ConfigDirector behaves is the author's own.

What to watch

  • Whether the MCP interface really enforces the same typed bounds as the dashboard when an assistant writes a value, which the post asserts for all interfaces.
  • Whether other flag services move past boolean, string, number and JSON to typed constraints with bounds.
  • Any published post-mortem attributing an outage to a config value that a range bound or JSON schema would have refused at save time.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories