Skip to content

fix(dashmate): handle nullable ZeroSSL expiry dates - #4415

Open
shumkov wants to merge 1 commit into
v4.1-devfrom
fix/zerossl-null-expiry
Open

fix(dashmate): handle nullable ZeroSSL expiry dates#4415
shumkov wants to merge 1 commit into
v4.1-devfrom
fix/zerossl-null-expiry

Conversation

@shumkov

@shumkov shumkov commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Issue being fixed or feature implemented

dashmate ssl obtain aborts with Cannot read properties of null (reading 'split') when ZeroSSL returns a draft or pending certificate. ZeroSSL documents expires as null until the certificate is issued, but Dashmate previously parsed it as an unconditional date string.

What was done?

  • Preserve the nullable expiry while a ZeroSSL certificate is not yet issued.
  • Treat a certificate without an expiry as not expired so the validation flow can continue.
  • Add regression coverage using the pending-certificate response shape.

How Has This Been Tested?

  • The focused regression test failed with the reported null.split error before the fix and passes after it.
  • All ZeroSSL unit specs pass: 13 tests.
  • ESLint reports no errors in the changed files. It retains one pre-existing unused suppression warning in Certificate.js.
  • The complete Dashmate unit suite could not start because this worktree does not contain the generated packages/wasm-dpp/dist/index.js artifact.

Breaking Changes

None.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Compound Engineering

ZeroSSL leaves expires null while certificates are draft or pending validation. Preserve that state and avoid treating an unissued certificate as expired.\n\nTest would have caught this in CI: ✖ before fix, ✔ after.
@github-actions github-actions Bot added this to the v4.1.0 milestone Aug 18, 2026
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fd9303a6-2852-468e-a6bd-a34d8dc5bd17

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@thepastaclaw

thepastaclaw commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

⛔ Blockers found — Opus deferred (commit 1b409ab)
Canonical validated blockers: 1

@shumkov shumkov self-assigned this Aug 18, 2026

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Preliminary review — Codex only

The nullable parsing change fixes the reported null.split failure in the interactive obtain flow, but it introduces an unhandled null-expiry path in the background renewal scheduler. A helper restart while a persisted ZeroSSL certificate is still draft or pending now terminates the helper instead of retrying or completing validation, so changes are required before merge.
Source: reviewer backend model: gpt-5.6-sol; final verifier backend model: gpt-5.6-sol. Orchestration only, not reviewer evidence: openclaw-agent/cliproxy/gpt-5.6-sol.

Validated blockers were found in the Codex precheck. Opus is deferred until a fresh Codex revalidation clears the blocker gate.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed)
  • Verifier: gpt-5.6-sol — verifier
  • Sonnet: not run (deferred by blocker gate)

🔴 1 blocking

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/dashmate/src/ssl/zerossl/Certificate.js`:
- [BLOCKING] packages/dashmate/src/ssl/zerossl/Certificate.js:109-110: Null expiry now crashes the background renewal scheduler
  Returning `false` for a missing expiry routes the background scheduler into its non-expired branch. `scheduleRenewZeroSslCertificateFactory.js` then constructs `new Date(certificate.expires)`, subtracts three days, and passes the resulting December 1969 date to `cron` 2.1.0; `job.start()` throws `WARNING: Date in past. Will never be fired.` outside the scheduler's retry `try` block. This is reachable because the certificate-creation task persists `ssl.enabled`, the ZeroSSL provider, and the certificate ID immediately after creating the draft, before verification and issuance complete. If the helper starts or restarts while that certificate remains draft or pending, the exception escapes the awaited scheduler startup and terminates the helper. Previously, parsing the null expiry threw inside `getCertificate` and entered the one-hour retry path. Add explicit null-expiry handling in the scheduler that resumes obtain/validation or schedules a retry, and cover this caller with a pending-certificate regression test.

Comment on lines +109 to +110
if (this.expires === null) {
return false;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔴 Blocking: Null expiry now crashes the background renewal scheduler

Returning false for a missing expiry routes the background scheduler into its non-expired branch. scheduleRenewZeroSslCertificateFactory.js then constructs new Date(certificate.expires), subtracts three days, and passes the resulting December 1969 date to cron 2.1.0; job.start() throws WARNING: Date in past. Will never be fired. outside the scheduler's retry try block. This is reachable because the certificate-creation task persists ssl.enabled, the ZeroSSL provider, and the certificate ID immediately after creating the draft, before verification and issuance complete. If the helper starts or restarts while that certificate remains draft or pending, the exception escapes the awaited scheduler startup and terminates the helper. Previously, parsing the null expiry threw inside getCertificate and entered the one-hour retry path. Add explicit null-expiry handling in the scheduler that resumes obtain/validation or schedules a retry, and cover this caller with a pending-certificate regression test.

source: ['codex']

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