Crosspost to Inkwell — Technical Changelog (continued)

ΞVΞ🦋
ΞVΞ🦋
3 min read

03/15/26 — 03/16/26 — Post-Submission Bug Fixes & New Features

03/15/26 — “Publishing failed” error with WordPress 6.9.4

  • Root cause: transition_post_status hook was making synchronous HTTP calls to the Inkwell API inside the Gutenberg REST API request, blocking the response and triggering a publish failure
  • Fix: detect REST_REQUEST and defer crosspost execution using wp_schedule_single_event + spawn_cron()
  • Follow-up: cron never fired on host due to blocked loopback HTTP requests — replaced with shutdown action hook
  • ignore_user_abort(true) added to keep DB connections alive after response is sent
  • fastcgi_finish_request() called when available so PHP-FPM flushes the response to the browser before the crosspost runs
  • Wrapped shutdown execution in try/catch (\Throwable) to surface silent fatal errors
  • Fixed add_transient() unavailable in shutdown context after fastcgi_finish_request() — replaced transient lock with direct get_post_meta() check and force=true call in shutdown path
  • Retained cron hook registration for any events already queued from previous version

03/15/26 — Debug Log page

  • New admin page at Settings → Crosspost to Inkwell → 🪲 Debug Log
  • Enable/disable toggle — off by default to avoid storing sensitive data unnecessarily
  • Dark terminal-style log viewer, color-coded: green for success, red for errors, blue for outgoing requests, orange for API responses
  • Refresh button (live AJAX reload) and Clear Log button with confirmation prompt
  • Log stored in wp_options under inkwell_debug_log, capped at 200 entries
  • Debug Log link added to settings page header and plugin action links row
  • 26 log points added throughout the crosspost flow:
    • Cron/shutdown deferral and execution
    • Crosspost start (post ID, force flag, post status)
    • Transient lock and already-posted guard hits
    • Every outgoing API request (method, URL, payload keys)
    • Every API response (HTTP status code + first 600 chars of body)
    • Image upload — file read, encode, upload, result
    • Crosspost success with entry URL
    • All error and skip paths

03/15/26 — Verify Key: reads live field value

  • inkwell_ajax_verify_key was reading the API key only from saved wp_options, so clicking Verify Key before saving always returned “No API key entered”
  • Fix: JS now reads the current value of #inkwell_api_key and passes it in the AJAX request; PHP handler uses the submitted key if present, falls back to saved option

03/15/26 — API key field: show/hide eye toggle

  • Added 👁 / 🔒 toggle button inline with the API key <input type="password"> field
  • Button switches field between password and text type on click
  • aria-label updates on toggle for screen reader accessibility
  • Typing in the key field clears the connected account status display so re-verification is obvious

03/16/26 — Persistent connected account display

  • After a successful Verify Key, the connected account name and handle are now saved to wp_options and displayed persistently on page load — no longer disappears on refresh
  • connected_display_name and connected_username added to plugin options defaults and sanitize callback
  • inkwell_ajax_verify_key refactored to make a single /api/me call (previously called it twice — once in inkwell_verify_credentials() and once again to extract data), saving account info and building the response message from the same result
  • On verify failure, saved account info is cleared so stale data from a previous key is never shown
  • Sanitize callback updated to pass through connected_display_name and connected_username from $input when present — previously always read from $existing (old DB value), silently overwriting the newly saved name on every update_option call
  • wp_kses() used instead of sanitize_text_field() for display name to preserve emoji and Unicode characters (e.g. ΞVΞ🦋)
  • API key change (via settings save) clears connected account info so stale name from previous key is never displayed

ΞVΞ🦋
ΞVΞ🦋

@eve · Blogger • Artist • Cellist • Gamer • IT chick • Feminist • 🍉📍 NY

← Feed

Marginalia1

ΞVΞ🦋
ΞVΞ🦋3h ago

What I found funny was it took me several prompts working with Claude to find the cause of the publishing error. “He” kept guessing, going back and forth saying it was this or that and never got it right. It wasn’t until I told him to okay, create a debug log, I then used that debug log in WordPress that printed the silent errors that were going on. Only then was Claude able to figure out what the problem was to fix it. Goes to show that AI can’t proactively reason for itself (at least not yet). It still needs a human to guide it, so you still need some kind of a basic idea about how coding works , or it will just have you going around in circles like a dog chasing its tail.

Luckily, Wordpress hadn’t reviewed my plugin submission yet so I was able to make the corrections before it got published.