Skip to content

ci: reject field names that generated code cannot address - #1740

Open
u9g wants to merge 2 commits into
mainfrom
jason/proto-reserved-word-lint
Open

ci: reject field names that generated code cannot address#1740
u9g wants to merge 2 commits into
mainfrom
jason/proto-reserved-word-lint

Conversation

@u9g

@u9g u9g commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Follows #1738, which is already merged — this branch is rebased onto it, so the gate is green on main as it stands.

from reached main and surfaced days later as a red mypy gate in python-sdks, on a PR that had only bumped the submodule. Nothing here could have caught it: protocol generates Go and JS in CI, never Python, and Go is immune because its capitalization rules dodge the collision.

Two checks

core::0140::reserved-words (api-linter) matches field names against a maintained list of Java, JavaScript and Python 3 keywords. Verified against the pre-rename proto — it flags both fields and exits 1:

livekit_agent_simulation.proto:273  '"from" is a reserved word in a common language and should not be used.'
livekit_agent_simulation.proto:292  '"from" is a reserved word in a common language and should not be used.'

Only that one rule is enabled. api-linter's defaults encode Google's whole API style guide, which these protos don't follow — 413 problems on that one file. Note the flags --disable-rule core --enable-rule core::0140::reserved-words do not work, disable wins; it takes a config file.

The Python stub check generates the stubs and greps for **kwargs, which is what protoc emits when it cannot name a field's parameter. It answers to the generator instead of a list — worth having separately, because the generator's behaviour is subtler than any keyword list suggests. Probing it: from/finally degrade to **kwargs; the soft keywords match/type are fine; and a field named self is handled by renaming the receiver to self_.

The four fields that predate the check

Suppressed by path in .api-linter.yaml, with reasons, rather than with the in-proto (-- api-linter: ... --) comment — protoc copies that comment into the generated code of every language, so four suppressions would have landed in the public API docs of every SDK:

Field Word Why it stays
TrickleRequest.final, TranscriptionSegment.final final On the wire since 2021; renaming breaks every SDK. Java-only, and its generator mangles it.
FunctionCall.arguments arguments Not a Python keyword; JS restricts it only inside a strict-mode function body, not as a property name.
SIPCall.from (rpc/io.proto) from Names the SIP From header. rpc/ is Go-only, so it never reaches a Python stub — a rename is a prerequisite if that changes.

The path suppression is file-scoped, so a new keyword field in one of those four files would slip past api-linter. Their Python side stays covered: the stub check takes no suppressions.

Both steps were run locally, green on this tree and exit 1 when start_time is reverted to from. No proto or generated-code changes — the diff is the config and the CI job.

A field named `from` reached main and only surfaced days later as a red mypy
gate in python-sdks, on an unrelated PR: protoc's --pyi_out cannot emit a Python
keyword as a parameter name, so it drops the attribute and falls back to an
untyped **kwargs. Nothing in this repo's CI could see it — protocol generates Go
and JS, never Python.

Two checks, because they answer to different authorities. api-linter's
core::0140::reserved-words matches a maintained list of Java, JavaScript and
Python 3 keywords; the stub check runs the generator and looks for the **kwargs
it emits when it gives up on a name.

api-linter's default rule set reports 413 problems on one of these files, so the
config enables that single rule. Four fields predate the check and are suppressed
by path in the config rather than with the in-proto comment, which protoc copies
into every language's generated code.
@changeset-bot

changeset-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 44ed0be

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment thread .github/workflows/buildtest.yaml Fixed
CodeQL flags a job that leaves GITHUB_TOKEN at its default permissions. The job
reads the repo and uses the token only for setup-protoc's release downloads.
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.

2 participants