Skip to content

push_to_wiki: idempotent delete on missing page#16

Merged
daharoni merged 1 commit into
mainfrom
idempotent-delete-on-missing
May 11, 2026
Merged

push_to_wiki: idempotent delete on missing page#16
daharoni merged 1 commit into
mainfrom
idempotent-delete-on-missing

Conversation

@daharoni
Copy link
Copy Markdown
Contributor

A delete API call for a page that no longer exists currently returns `error.code = "missingtitle"`, gets counted as a generic error, and trips `sys.exit(1)` — even though the post-state ("page not on the wiki") matches the intent.

Real failure mode

The recent dispatch with `base_ref=6348e17` (force re-sync from the initial commit) hit this: the diff included two phantom keys (`aharoni2019`, `cai2016`) whose pages had been manually deleted on the wiki long ago. Both got reported as errors, workflow exited 1, despite the two real-target pages (`Publication/guo_2023_miniscopelfov`, `Publication/zhao_2025_minixl`) being created successfully.

The same pattern will recur every time a curator manually cleans up a page on the wiki and a later sync's diff still thinks it needs to delete it.

Fix

Treat `missingtitle` on delete as idempotent success: the page is absent, which is what the intent was.

`WikiClient.delete_page` now returns `(True, MISSING_PAGE)` on `missingtitle`. The caller logs it as `(already absent)` and bumps a separate `already_missing` counter so the summary line stays accurate (deleted-count means "actually deleted by this run") without tripping the error path.

Output examples:

```

  • Publication/foo (already absent)
  • Publication/bar
    ...
    Done: 2 created, 0 updated, 0 unchanged, 1 deleted, 1 already absent, 0 errors
    ```

The summary's `already absent` segment only appears when non-zero, so the common no-deletion case stays the same shape as before.

Tests

112/112 pass. No new tests — this is a 3-line behavior change to a function with no existing test coverage. Adding a tests/test_push_to_wiki.py with WikiClient mocks would be a worthwhile follow-up but is out of scope here.

🤖 Generated with Claude Code

…uccess

Before: a delete API call for a page that no longer exists on the wiki
returned `error.code = "missingtitle"`, the script counted it as a
generic error, and the workflow exited 1 — even though the post-state
("page not on wiki") matched the intent.

This is a real-world case: pages may be manually deleted by a curator on
the wiki, or be cleaned up by a previous sync that ran with a different
base_ref. The recent dispatch with `base_ref=6348e17` hit this on the
two phantom keys from the initial commit (`aharoni2019`, `cai2016`) —
both already absent, both reported as "errors", workflow failed despite
both real-target pages being created successfully.

Make delete_page idempotent on `missingtitle`: return success with a
sentinel `MISSING_PAGE` marker. Caller logs it as `(already absent)` and
keeps a separate `already_missing` counter so it stays out of the
deleted-count (the wiki didn't actually do anything) but doesn't trip
the error path. Summary line includes the new counter only when it's
non-zero, so output stays clean for the common case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Citations Summary

Status: ✅ All checks passed

Metric Count
Total citations 2
Added 0
Edited 0
Removed 0
Keys normalized 0

@daharoni daharoni merged commit 2a93667 into main May 11, 2026
3 checks passed
@daharoni daharoni deleted the idempotent-delete-on-missing branch May 11, 2026 16:59
@daharoni daharoni mentioned this pull request May 11, 2026
daharoni added a commit that referenced this pull request May 11, 2026
Used locally during wiki credential debugging \(see context from PR #15/#16\).
Adding to .gitignore so it can't be accidentally committed by anyone who
creates their own .secrets file in a clone of the repo.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant