Skip to content

fix(cron): handle undefined/null input in parseAbsoluteTimeMs#69574

Closed
Eruditi wants to merge 19 commits into
openclaw:mainfrom
Eruditi:fix/cron-parse-undefined
Closed

fix(cron): handle undefined/null input in parseAbsoluteTimeMs#69574
Eruditi wants to merge 19 commits into
openclaw:mainfrom
Eruditi:fix/cron-parse-undefined

Conversation

@Eruditi

@Eruditi Eruditi commented Apr 21, 2026

Copy link
Copy Markdown

The parseAbsoluteTimeMs function would throw 'Cannot read properties of undefined (reading trim)' when called with undefined or null input. This could happen when cron jobs had malformed or missing schedule data, particularly when displaying cron job lists via openclaw cron list.

This fix adds a null/undefined guard at the start of the function, returning null early instead of throwing a TypeError.

Fixes #69547

The parseAbsoluteTimeMs function would throw 'Cannot read properties of undefined (reading trim)' when called with undefined or null input. This could happen when cron jobs had malformed or missing schedule data.

Fixes openclaw#69547
@greptile-apps

greptile-apps Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a null/undefined guard to parseAbsoluteTimeMs in src/cron/parse.ts, preventing a TypeError when the function is called with missing schedule data. The fix is minimal and correct, and the accompanying tests cover undefined, null, empty string, whitespace-only, and valid input cases.

Confidence Score: 5/5

Safe to merge — the change is a minimal defensive guard with full test coverage and no side effects on existing callers.

The fix is a two-line null check with an updated type signature; all existing behavior is preserved and the new edge cases are thoroughly tested.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(cron): handle undefined/null input i..." | Re-trigger Greptile

Eruditi and others added 2 commits April 21, 2026 11:53
The openclaw update command would run a full npm install even when
the installed version already matched the latest registry version.
This caused unnecessary work, wasted time, and could be dangerous on
resource-constrained systems.

This fix adds a version comparison before invoking the package manager.
If the current version equals the target version (and no explicit tag
was requested), the update is skipped with an informative message.

Fixes openclaw#69412
@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: S and removed size: XS labels Apr 21, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c795c4347d

ℹ️ 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".

Comment on lines +1048 to +1049
defaultRuntime.exit(0);
return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Continue post-update plugin sync on no-op package updates

This new early-return path exits the command before the plugin update flow (runPostCorePluginUpdate) is reached later in updateCommand, so openclaw update no longer updates plugins when the core package version is already current. In practice, package installs at the latest core version can still have pending bundled/npm plugin changes, and this branch now skips those updates entirely.

Useful? React with 👍 / 👎.

Comment on lines +1030 to +1035
updateInstallKind === "package" &&
currentVersion &&
targetVersion &&
currentVersion === targetVersion &&
!explicitTag
) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist requested channel before early no-op exit

This condition returns before the later config-write block that persists --channel, so a user request like openclaw update --channel beta is dropped whenever currentVersion === targetVersion (for example when beta resolves to latest). That leaves update.channel unchanged even though the command succeeded, so subsequent update behavior does not match the user’s explicit channel selection.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2e76d24bb2

ℹ️ 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".

Comment on lines +1039 to +1045
defaultRuntime.log(
JSON.stringify({
status: "ok",
message: `Already on ${currentVersion} (latest). Nothing to update.`,
currentVersion,
targetVersion,
}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Emit UpdateRunResult on no-op JSON updates

When openclaw update --json takes this no-op branch (currentVersion === targetVersion), it prints a custom object with defaultRuntime.log(JSON.stringify(...)) and returns, instead of using the normal printResult/defaultRuntime.writeJson(UpdateRunResult) path. That means no-op responses drop fields like mode, steps, and durationMs, so machine consumers expecting the documented UpdateRunResult schema (see docs/cli/update.md) will break specifically on already-up-to-date runs.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b9406bb6b

ℹ️ 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".

Comment on lines +1030 to +1034
updateInstallKind === "package" &&
currentVersion &&
targetVersion &&
currentVersion === targetVersion &&
!explicitTag

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip no-op exit when OPENCLAW_UPDATE_PACKAGE_SPEC is active

This early-return condition treats matching currentVersion/targetVersion as a universal no-op, but it ignores package-spec overrides resolved via resolveGlobalInstallSpec (including OPENCLAW_UPDATE_PACKAGE_SPEC). In override workflows, users intentionally reinstall from a custom tarball/git spec even when semver matches latest; with this branch, openclaw update exits before running the installer, so the requested package source is never applied.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0254bab2d4

ℹ️ 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".

);
}
defaultRuntime.exit(0);
return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Continue plugin sync when core package update is skipped

Fresh evidence: this commit adds an early return on currentVersion === targetVersion before the later runPostCorePluginUpdate(...) path. For package installs that are already on the target core version but still have pending bundled/npm plugin changes, openclaw update now exits at this branch and never runs plugin synchronization, leaving plugin state stale after a successful update command.

Useful? React with 👍 / 👎.

);
}
defaultRuntime.exit(0);
return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist requested channel before returning on no-op update

Fresh evidence: the newly added no-op exit returns before the config persistence block that writes update.channel. When a user runs openclaw update --channel <stable|beta> and that channel resolves to the same core version, the command reports success but drops the channel change, so future updates continue using the previous stored channel instead of the user’s explicit selection.

Useful? React with 👍 / 👎.

Comment on lines +1039 to +1043
defaultRuntime.log(
JSON.stringify({
status: "ok",
message: `Already on ${currentVersion} (latest). Nothing to update.`,
currentVersion,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return UpdateRunResult shape for no-op JSON updates

Fresh evidence: this commit’s opts.json no-op path writes a custom JSON blob directly with defaultRuntime.log(JSON.stringify(...)) instead of using the standard update result printer. That makes no-op runs emit a different schema than normal UpdateRunResult output (missing fields like step/mode timing data), which can break automation that relies on a consistent JSON contract.

Useful? React with 👍 / 👎.

Comment on lines +1030 to +1034
updateInstallKind === "package" &&
currentVersion &&
targetVersion &&
currentVersion === targetVersion &&
!explicitTag

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor package-spec overrides in no-op package checks

Fresh evidence: the new no-op condition gates only on !explicitTag and does not account for packageInstallSpec overrides resolved via resolveGlobalInstallSpec (for example OPENCLAW_UPDATE_PACKAGE_SPEC). In override workflows that intentionally reinstall from a custom source at the same semver, this branch exits before install, so the requested override is silently ignored.

Useful? React with 👍 / 👎.

@Eruditi

Eruditi commented Apr 21, 2026

Copy link
Copy Markdown
Author

Thank you for the review! The fix addresses the issue by adding a null/undefined guard at the start of the parseAbsoluteTimeMs function, returning null early instead of throwing a TypeError. This ensures that cron jobs with malformed or missing schedule data can still be listed without causing an error.

The change is minimal and focused, only affecting the cron time parsing logic. Please let me know if there are any further adjustments needed, or if this can be merged.

@openclaw-barnacle openclaw-barnacle Bot added the r: too-many-prs Auto-close: author has more than twenty active PRs. label Apr 22, 2026
@openclaw-barnacle

Copy link
Copy Markdown

Closing this PR because the author has more than 10 active PRs in this repo. Please reduce the active PR queue and reopen or resubmit once it is back under the limit. You can close your own PRs to get back under the limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes r: too-many-prs Auto-close: author has more than twenty active PRs. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: cron TypeError: Cannot read properties of undefined (reading 'trim')

1 participant