Skip to content

Cron crashes when post format maximum length is non-numeric #1108

Description

@pirate-bot

Summary

Scheduled sharing can terminate with TypeError: Unsupported operand types: string - int when formatting a post.

Expected behavior: a saved post format supplies a usable content-length value and scheduled sharing proceeds.

Actual behavior: a non-numeric saved maximum-length value reaches content-length arithmetic and crashes the cron request.

Impact: affected scheduled shares are not processed while this error occurs.

Customer context

  • Product / area: Revive Social scheduled sharing and post-format content generation
  • Version: 9.4.1
  • Environment: WordPress 7.0.2; PHP 8.3.32; cron request
  • Integration / third party: Not applicable
  • Reported error / symptom: TypeError: Unsupported operand types: string - int
  • Impact: 23 telemetry occurrences across one distinct site during the query window.

Reproduction notes

  1. Configure an account with a post format whose persisted maximum_length is a non-numeric string.
  2. Queue a post for that account and allow its scheduled cron event to run.
  3. The reported path reaches post-content formatting and production telemetry shows TypeError: Unsupported operand types: string - int.

Reproduction is source-confirmed from the production stack and tagged code; the original saved value is unavailable.

Diagnosis

Conclusion

Production telemetry identifies Rop_Post_Format_Helper::build_content() at the reported source location during cron processing. In tagged v9.4.1, maximum_length is read from persisted post-format data without normalization and then used as the left operand in string-minus-integer arithmetic. The REST and model save paths permit non-numeric strings to be stored, making the reported PHP 8.3 TypeError a confirmed product defect.

Where this likely occurs

  • includes/admin/helpers/class-rop-post-format-helper.phpRop_Post_Format_Helper::build_content() lines 147-153 reads $this->post_format['maximum_length'] directly; lines 253-265 calculates $max_length - ... - $custom_length, with line 257 matching telemetry.
  • includes/admin/class-rop-rest-api.phpRop_Rest_Api::save_post_format() lines 371-390 only caps Twitter values after an integer comparison; non-numeric strings are not normalized and non-Twitter formats have no equivalent validation.
  • includes/admin/models/class-rop-post-format-model.phpRop_Post_Format_Model::add_update_post_format() approx. lines 114-118 persists supplied format data through the generic model storage path without field type enforcement.
  • includes/admin/models/class-rop-queue-model.phpRop_Queue_Model::prepare_post_object() lines 431-436 invokes get_formated_object(); includes/admin/class-rop-admin.phpRop_Admin::rop_cron_job() lines 1218-1243 reaches that method for due queued posts.
  • v9.4.1 points at 752e0ee6c324c134b8c8ddd85818b760654f8d08. git blame attributes the subtraction at line 257 to 371c0ad86; the expression remains in the release tag.

Engineering notes

  • Default post-format values intentionally represent maximum_length as numeric strings, such as Twitter's '240', in includes/admin/class-rop-global-settings.phpRop_Global_Settings::$post_format_defaults approx. lines 205-449. Numeric strings coerce in the observed expression; the failure evidence is consistent with a non-numeric persisted string.
  • The Vue editor presents maximum_length as a number input, but the request path sends the complete format data and does not provide a server-side schema boundary: vue/src/vue-elements/accounts-selector-panel.vue approx. lines 248-263 and includes/admin/class-rop-rest-api.php lines 94-101.
  • Legacy migration also copies the previous length option into the post format without type normalization: includes/admin/helpers/class-rop-db-upgrade.phpRop_DB_Upgrade::migrate_post_formats() approx. lines 228-293.
  • get_custom_length() derives an integer from a scalar custom_text value at includes/admin/helpers/class-rop-post-format-helper.phpRop_Post_Format_Helper::get_custom_length() lines 414-435. The inspected telemetry and source location point to maximum_length as the string operand in the reported arithmetic error.

Test coverage status

  • tests/test-post-format.phpTest_RopPostFormat::test_post_format() lines 189-220 asserts a default string maximum length and saves an integer value, but does not format a post with invalid persisted length data.
  • tests/test-x-premium-limit.php covers the Twitter upper-bound behavior, but its assertions cast saved values to integers and do not exercise non-numeric values during scheduled formatting.
  • No relevant coverage was found during inspection for a non-numeric persisted maximum_length reaching build_content() in the cron queue path.

What to verify or explore next

  • Reproduce scheduled formatting with a post format whose persisted maximum_length is a non-numeric string, on the supported PHP 8.3 environment.
  • Check whether post formats migrated from legacy options or saved through the REST route can contain non-numeric length values in affected installations.
  • Run the post-format and queue PHPUnit suites after adding coverage for the reported input and cron path.

Unknowns / follow-up

  • Telemetry does not contain the persisted post-format payload, so the exact non-numeric value and entry route are unknown.
  • The available evidence covers the free plugin repository; no Pro override of this arithmetic path was found during inspection.

Confidence

Confidence: 97/100

Production telemetry records 23 cron crashes on one site running v9.4.1/PHP 8.3.32, and the tagged source lets a persisted non-numeric maximum_length reach the exact failing string-minus-integer expression without type validation.

Crash telemetry

Occurrences 23
Distinct sites 1
First seen 2026-08-04 17:01 UTC
Last seen 2026-08-05 04:03 UTC
Crash location product:includes/admin/helpers/class-rop-post-format-helper.php:257
Request context cron
Inside Themeisle SDK no
Product versions 9.4.1
WP versions 7.0.2
PHP versions 8.3.32
SDK versions 3.3.58

Source: automated crash report — tweet-old-post, fingerprint e32435e67e4238ba8337cad9df1fcd3a
Generated by bug-report-triage (ID: bug-report-triage_6a72d18106df89.42530208)

Activity

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

Metadata

Metadata

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions