fix(cron): strip internal whitespace from model IDs in cron job normalization#66543
fix(cron): strip internal whitespace from model IDs in cron job normalization#66543Angfr95 wants to merge 2 commits into
Conversation
Greptile SummaryThis PR fixes internal-whitespace corruption in cron job model IDs by applying Confidence Score: 4/5
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 156cfcdd53
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| @@ -181,7 +181,7 @@ function coercePayload(payload: UnknownRecord) { | |||
| if ("model" in next) { | |||
| const model = parseOptionalField(TrimmedNonEmptyStringFieldSchema, next.model); | |||
| if (model !== undefined) { | |||
| next.model = model; | |||
| next.model = model.replace(/\s+/g, ''); | |||
There was a problem hiding this comment.
Keep spaces in alias model overrides
payload.model can be an alias (not just provider/model), but this replacement removes all whitespace, so an alias like "My Fast Model" is rewritten to "MyFastModel" and no longer matches alias resolution (which lowercases but preserves internal spaces). Since normalizeCronJobInput is also used when hydrating persisted jobs in src/cron/service/store.ts, existing cron jobs that rely on spaced aliases can start failing with invalid model after this change.
Useful? React with 👍 / 👎.
65b1f96 to
1b65e7e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1b65e7e895
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const fallbacks = normalizeTrimmedStringArray(next.fallbacks); | ||
| if (fallbacks !== undefined) { | ||
| next.fallbacks = fallbacks; | ||
| next.fallbacks = fallbacks?.map(f => f.replace(/\s+/g, '')) ?? fallbacks; |
There was a problem hiding this comment.
Preserve spaces in fallback aliases during normalization
Fallback entries can be alias strings, not just provider/model, and this normalization removes all internal whitespace from each fallback. An alias like "My Backup Model" is rewritten to "MyBackupModel", but alias matching in buildModelAliasIndex/resolveModelRefFromString lowercases while preserving internal spaces, so the fallback alias no longer resolves. Because normalizeCronJobInput is also used when reading persisted jobs in src/cron/service/store.ts, existing cron jobs with spaced fallback aliases can silently lose their fallback chain and fail instead of retrying on the intended model.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ec67ebe88
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const normalized = normalizeOptionalString(value); | ||
| if (normalized) { | ||
| payload[field] = normalized; | ||
| payload[field] = field === "model" ? normalized.replace(/\s+/g, '') : normalized; |
There was a problem hiding this comment.
Preserve spaces in top-level model aliases
copyTopLevelAgentTurnFields now strips all whitespace from top-level model values before moving them into payload.model, but top-level model hints are still a supported input path (for example in patch normalization) and aliases can legitimately contain internal spaces. Alias lookup lowercases but preserves internal spacing, so an alias like "My Fast Model" becomes "MyFastModel" here and no longer resolves, causing invalid model for updates/hydration that rely on the top-level compatibility path.
Useful? React with 👍 / 👎.
| const fallbacks = normalizeTrimmedStringArray(next.fallbacks); | ||
| if (fallbacks !== undefined) { | ||
| payload.fallbacks = fallbacks; | ||
| payload.fallbacks = fallbacks?.map(f => f.replace(/\s+/g, '')) ?? fallbacks; |
There was a problem hiding this comment.
Keep spaces when copying top-level fallback aliases
The top-level fallback compatibility path now applies .replace(/\s+/g, '') to each fallback entry, which breaks fallback aliases that include internal spaces. Fallback entries are resolved through the same alias machinery as primary model refs, where normalization trims and lowercases but does not remove inner spaces, so values like "My Backup Model" are rewritten to "MyBackupModel" and stop matching; jobs using top-level fallbacks patches then lose their intended fallback chain.
Useful? React with 👍 / 👎.
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Keep this PR open, but it is not merge-ready: the alias-preserving resolution-time direction is useful, yet the potential merge result still returns spaced slash-form refs unchanged in allow-any configs, leaves payload fallback refs on the raw fallback path, and has no real after-fix cron/provider proof. Canonical path: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review. So I’m closing this here because the remaining work is already tracked in the canonical issue. Review detailsBest possible solution: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection of current main and the potential merge result shows how spaced slash-form payload models and fallbacks flow through cron model selection into provider/fallback resolution without guaranteed compaction. Is this the best way to solve the issue? No. Resolution-time repair is the right boundary for preserving spaced aliases, but this PR is too narrow until allow-any success, fallback candidates, and real cron/provider proof are covered. Security review: Security review cleared: The diff changes TypeScript model-selection logic and tests only; no dependency, workflow, permission, secret-handling, network, or code-execution surface was added. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 6c88811b4bba. |
|
Codex review: needs changes before merge. What this changes: The PR branch changes cron normalization to strip all internal whitespace from Required change before merge: The bug is valid, the unsafe part of this PR is localized, and an automated replacement or branch repair can implement an alias-preserving fix with focused tests. Review detailsBest possible solution: Revise or supersede this PR with an alias-preserving repair: keep model values exact after trim, resolve aliases first, and only repair accidental whitespace for clear provider/model refs when the raw value fails resolution. Cover payload and top-level create/patch paths for both primary model and fallbacks. Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against acae48b790fa. |
9c5aa59 to
c8c782b
Compare
Revert blanket internal-whitespace collapse from normalize and instead apply it lazily at resolution time in resolveAllowedModelRefFromAliasIndex. The repair only fires for slash-form refs (provider/model) and only when the verbatim trimmed value fails alias lookup or allowlist check, so spaced aliases such as 'DeepSeek R1' are never mutated.
|
ClawSweeper PR egg 🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat. Where did the egg go?
|
|
Heads up: this PR needs to be updated against current |
|
This pull request has been automatically marked as stale due to inactivity. |
|
ClawSweeper applied the proposed close for this PR.
|
Summary
custom-1/ minimax/ minimax-m2.5-free), causing OpenRouter to reject them with400 ... is not a valid model ID (format).coercePayload()andcopyTopLevelAgentTurnFields()insrc/cron/normalize.tsnow strip all internal whitespace frommodelandfallbacksfields via.replace(/\s+/g, '').Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
TrimmedNonEmptyStringFieldSchemaonly.trim()s leading/trailing whitespace. LLMs frequently insert spaces around/and-separators when generating tool call parameters. The normalization layer had no guard against internal whitespace in model IDs.Regression Test Plan (if applicable)
src/cron/normalize.test.tsnormalizeCronJobCreatewith model"custom-1/ minimax/ minimax- m2.5- free"and fallbacks containing internal spaces should output clean IDs with zero whitespace.coercePayloadduring normalization — a unit test onnormalizeCronJobCreatecatches it at the exact mutation point.User-visible / Behavior Changes
Model IDs with accidental internal whitespace are now silently corrected instead of being persisted as-is. No config changes.
Diagram (if applicable)
Security Impact (required)
Repro + Verification
Environment
custom-1/minimax/minimax-m2.5-freeSteps
custom-1/minimax/minimax-m2.5-freecustom-1/ minimax/ minimax- m2.5- freeExpected
custom-1/minimax/minimax-m2.5-freeActual
custom-1/ minimax/ minimax- m2.5- freeEvidence
53/53 tests pass including new
"strips internal whitespace from model IDs"test.Human Verification (required)
normalizeCronJobCreatewith internal spaces in model and fallbacks fieldsReview Conversations
Compatibility / Migration
Risks and Mitigations
/and-delimiters without spaces.