Repository navigation
fix(config): bound OCTOP_PORT and --port to a bindable range - #1150
Merged
jubaoliang merged 2 commits intoSep 26, 2026
Merged
Conversation
OCTOP_PORT 只按 int() 解析、octop run --port 也只有 type=int,70000/-1 这类根本无法绑定的取值会盖掉 config.json 里本来可用的端口,进程死在 socket.bind 抛出的 OverflowError 里,报错既不含变量名也看不出端口来源; --port 更是在启动之前就把该值写进 config.json,之后每次 octop run 都继续继承。 现按 resolve_bind 已经支持的「0 表示由系统随机分配端口」把取值收口到 0-65535:环境变量越界沿用「告警 + 不覆盖」的既有契约回落配置文件端口, 命令行 --port 越界交给 click.IntRange 在使用期错误里拦下、不落盘。
`octop run --port` 现在会渲染成 `INTEGER RANGE … [0<=x<=65535]`,环境变量表也顺手写明 `OCTOP_PORT` 接受 0–65535(0 = 由系统随机分配),与 `OCTOP_LOG_LEVEL` 那行「One of …」的写法一致。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
OCTOP_PORTandoctop run --portaccept any integer, so a port no socket can ever bind —70000,-1— is treated as a valid override. It then outranks a perfectly goodconfig.jsonport and kills startup insidesocket.bind:The traceback names neither the key nor the value, and on the CLI path the damage is sticky:
env_bind_overrides()(src/octop/config.py:403-408) parses with bareint(). Its docstring promises that "an invalidOCTOP_PORTlogs a warning and yields no override, so the file/default value wins", but only a non-numeric value reaches that branch.70000parses fine, wins theconfig.jsoncomparison inresolve_bind()(src/octop/cli/commands/run.py:104) and inload_config()(src/octop/config.py:462-465), and the server never starts.--portistype=intwith no range, andoctop runpersists the CLI override toconfig.jsonbefore uvicorn is called (src/octop/cli/commands/run.py:180-182;test_run_writes_config_even_on_uvicorn_failurelocks in that ordering on purpose). So one typo'd port is saved, and every lateroctop runinherits the unusable value.Measured on pristine
develop@1d2b2558with only the new tests added:i.e. the baseline prints
Saved config to …and then starts uvicorn with the unbindable port.Changes Made
src/octop/config.py— an out-of-rangeOCTOP_PORTis dropped with the samelogger.warning(…, "ignoring override")shape the function already uses for a non-numeric value, so the file/default port wins as documented.src/octop/cli/commands/run.py—--portbecomesclick.IntRange(0, 65535)(the idiom already used atsrc/octop/cli/commands/memory.py:145), so a bad flag is a Click usage error that never reachesconfig.json.tests/unit/cli/test_run_bind_resolution.py— out-of-range env values fall back to the file port;OCTOP_PORT=0still means "OS-assigned".tests/unit/cli/test_run_cmd.py—--port 70000/--port -1exit non-zero, name the range, and leave noconfig.jsonbehind;--port 0still reaches uvicorn as0.CHANGELOG.md(### 修复under[Unreleased]), plus the two doc cells that state the accepted values (docs/configuration.md,docs/cli.md—--helpnow rendersINTEGER RANGE … [0<=x<=65535]).The two entry points fail differently on purpose: the env override already has a documented fallback contract, while a flag the operator typed explicitly must not silently start the server on a different port than requested — that one should say so and stop.
0stays in range deliberately.resolve_bind()readsport=0as "let the OS pick a free port" (src/octop/cli/commands/run.py:102-103), so a1-65535bound would break a documented feature; the control tests above pin both paths.Not touched:
_coerce_int()(src/octop/config.py:274) still accepts any int for keys such asOCTOP_DATABASE_PORT— those talk to another host and fail in their own way, so bounding them is a separate question; and aportwritten by hand intoconfig.jsonis still honoured as-is rather than second-guessed at startup.Target branch
develop(feature / fix — default)main(release/*orhotfix/*only)Type of change
Test plan
Windows 11, Python 3.12.11, branch
fix/env-port-range-guardofforigin/develop@1d2b2558:ruff check src tests→All checks passed!;ruff format --check src tests→1062 files already formatted(ruff 0.15.20 from the project venv)mypy src/octop→Success: no issues found in 519 source files(strict = truecomes frompyproject.toml, so this ismake typecheck)pytest tests/unit/cli -m "not live"→93 passed, 9 skipped— this covers both touched test files and their neighbourspytest -n auto -m "not live"— the whole non-live suite, i.e.make test's command →19 failed, 3651 passed, 118 skipped in 449.74s(started atea10de20; the one commit made after it started,410645e8, edits two markdown doc cells)develop, not caused by this change: the same two directories on a pristine1d2b2558worktree fail with the same 19 node ids (pytest -n auto tests/unit/db tests/unit/backup -m "not live"→19 failed, 190 passed, 2 skipped), and none of the files this PR touches are imported by them.make allwas not run as a single command:makeis not available in this environment. Its steps were run individually as listed above (ruff check + format check, mypy, pytest);make all's remaining steps (Prettier / dashboard build) are untouched by this diff, which contains nodashboard/change.make allpasses locally — see the note above: the equivalent gate commands pass, themakewrapper itself was not runChecklist
CHANGELOG.md(if user-facing)docs/configuration.md+docs/cli.mdonlydevelop, branch contains only this fix (2 commits: the fix + the doc cells)Who did this work: the analysis, the patch and the tests were written by an agent (Qoder CLI) working for
Lesereingrape, and the red/green numbers above were measured by that agent in one session. Nothing here has been read by a human on our side yet, so treat the diff as agent-authored until someone says otherwise.