When a social media post appears to fail, do not send it again immediately. First determine whether it was rejected before acceptance, definitely failed after acceptance, may have succeeded despite a timeout, or is already public. Reconcile the evidence and correct the cause. Retry only if the attempt still uses the same approved content, account, and timing.
A timeout is the risky case. The publishing system or provider may have accepted the request before the connection failed. Sending it again could create a duplicate, so check the known post state and inspect the destination first.
Developers and operators can use the stage model, decision tree, and failure log below to recover agent-driven publishing attempts. The same process applies whether an agent calls a connector through an API, CLI, or another supported client.
Treat publishing as four checkpoints
Separate recovery into preflight, submission, provider delivery, and reconciliation. "The post failed" is too vague to determine what happens next.
1. Preflight
Before submitting anything, use preflight to confirm that the intended operation is valid. Discover the live integration and its settings schema, then check the account, content, media, destination-specific settings, and intended time.
For a post with media, upload each asset first and keep the Groniz path or reference returned by the upload operation. A local filename or arbitrary URL cannot replace that reference. The multi-platform media upload guide explains the sequence.
A validation rejection at this checkpoint is straightforward: no publishing request should have crossed the submission boundary. Correct the invalid input, repeat preflight, and keep the approval binding intact.
2. Submission
At submission, the publishing system receives a request to schedule or send the post. Record the attempt and its result before taking another action.
Acceptance shows only that the request entered the workflow, not that the provider published the post. A timeout or broken connection does not prove rejection either. The receiver may have accepted the request before the response was lost.
Treat transport errors as ambiguous unless you have positive evidence that nothing was accepted. Do not turn "I did not receive a success response" into "the post definitely failed."
3. Provider delivery
At provider delivery, the destination decides whether to accept and publish the post. It may reject work that passed an earlier validation step. Text formats, media support, scheduling behavior, and required settings differ across 32+ networks.
Groniz handles OAuth, per-platform formatting, scheduling, and delivery across those networks, but providers still behave differently. When one channel fails while others succeed, record the destination and stage for that channel.
4. Reconciliation
Reconciliation compares what the caller observed with what actually happened. List or check the known post state through the supported workflow, then inspect the destination where possible. Compare any public result with the approved content, account, and intended publication time.
This is the only checkpoint that can safely resolve an ambiguous timeout. If the post is public, record confirmed publication and stop. If it is not public but the available state still does not prove failure, escalate for investigation.
For a wider view of these boundaries, see the AI agent social media publishing lifecycle and the scheduling architecture for AI agents.
Failure recovery decision tree
Use this tree after every non-success response or missing delivery confirmation:
START: The expected post is not yet verified
|
+-- Did preflight or submission return a clear validation rejection?
| |
| +-- YES -> VALIDATION REJECTION
| Record the rejected input and rule.
| Correct the cause and run preflight again.
| If content, account, destination, or timing changed -> RETURN TO REVIEW.
| Otherwise continue to SAFE RETRY checks.
|
+-- Is there positive evidence that an accepted post will not publish
| or that the provider rejected it?
| |
| +-- YES -> CONFIRMED FAILURE
| Record the evidence and root cause.
| Correct the cause.
| Continue to SAFE RETRY checks.
|
+-- Did the request time out, disconnect, or return an outcome that
| does not prove acceptance or rejection?
| |
| +-- YES -> AMBIGUOUS OUTCOME
| Do not retry yet.
| List/check known state and inspect the destination.
| |
| +-- Expected post found -> CONFIRMED PUBLICATION -> STOP.
| |
| +-- Definitive failure found -> CONFIRMED FAILURE.
| |
| +-- Still uncertain -> HOLD AND ESCALATE; do not retry.
|
+-- Is the expected post present on the intended destination and account?
|
+-- YES -> CONFIRMED PUBLICATION
| Save the evidence and close the incident. Do not retry.
|
+-- NO, with definitive non-publication evidence -> CONFIRMED FAILURE.
SAFE RETRY checks:
|
+-- Is the failure cause corrected?
+-- Is non-publication confirmed?
+-- Are the approved content, account, destination, and timing unchanged?
+-- Has current state been recorded?
|
+-- ALL YES -> SAFE RETRY: submit one controlled attempt and reconcile again.
|
+-- ANY NO -> RETURN TO REVIEW or HOLD; do not retry.
"Safe retry" is an operational decision, not a claim that an API request is idempotent. It reduces duplicate risk by requiring confirmed non-publication and an unchanged approval envelope before another submission.
Copyable failure log template
Store the failure record in your own application or incident system. The fields below belong to the operator. They are not Groniz response fields or an API schema.
incident_id: ""
opened_at: ""
operator_or_agent: ""
approved_envelope:
approval_reference: ""
content_reference: ""
content_fingerprint: ""
integration_or_account_reference: ""
destination: ""
intended_publish_time: ""
media_references: []
attempt:
attempt_number: 1
phase: "preflight | submission | provider_delivery | reconciliation"
started_at: ""
finished_at: ""
caller_observation: ""
request_or_job_reference_if_available: ""
evidence:
validation_message: ""
known_state_check: ""
destination_check: ""
checked_at: ""
attachments_or_log_links: []
classification:
outcome: "validation_rejection | confirmed_failure | ambiguous_outcome | confirmed_publication"
reason: ""
failure_cause: ""
decision:
next_action: "correct_and_preflight | reconcile | safe_retry | return_to_review | hold | close"
decided_by: ""
decided_at: ""
retry_cause_corrected: false
non_publication_confirmed: false
approved_envelope_unchanged: false
resolution:
final_outcome: ""
public_post_reference_if_available: ""
resolved_at: ""
notes: ""
The content fingerprint can be any stable application-side reference that helps an operator compare attempts. It is not a provider deduplication key. An internal incident ID can correlate evidence, but it does not make publishing API requests idempotent.
How to handle each outcome
Validation rejection
Record the failed rule and the exact stage. Refresh the live integration and settings schema before correcting the request because cached assumptions about a destination can be wrong. Re-upload media only if the existing reference is invalid or the asset itself must change.
If the correction changes the wording, media, account, destination, or publication timing, the operation no longer matches its approval. Send it back through the process described in human approval for AI social posts. A seemingly mechanical validation fix can still change what gets published.
Confirmed failure
A clear provider rejection or a known state that definitively reports non-publication can establish failure. A missing response cannot.
Find and correct the cause before another attempt. The correction may involve refreshing an invalid configuration, replacing an incompatible media asset, or reconnecting the intended account. Follow the live schema and supported workflow instead of hard-coding one error taxonomy for every provider.
Rerun preflight and the safe-retry checks. Submit one controlled attempt, record it, and return to reconciliation.
Ambiguous outcome
Stop all retries. Preserve the timestamps, caller observations, any returned reference, and the approved envelope. List or check the known state, then inspect the intended destination and account.
Search for the expected content around the intended publication window. If destination formatting can change, compare the account, media, and timing as well as the text. When the destination provides too little evidence and the known state remains unclear, hold the incident for operator review. Uncertainty is not permission to resend.
Confirmed publication
Capture the public post reference when available, note when it was verified, and close the incident. Do not retry just because the original caller timed out or the local worker still reports an error. The public post settles the delivery question.
Build the retry worker around evidence
A retry worker should receive a recovery decision, not just an error. Its input should include the approved envelope, classification, correction evidence, and reconciliation result so it cannot blindly replay every failed task.
Enforce three gates:
- Cause gate: the recorded failure cause has been corrected.
- Publication gate: reconciliation confirms that the expected post is not already public.
- Approval gate: content, account, destination, and timing still match the approved operation.
After a retry, the worker must return to reconciliation. Request acceptance does not prove delivery.
This design makes no assumptions about automatic retries, guaranteed idempotency, webhooks, a dead-letter queue, or particular status and error fields. Any such behavior must come from the current documented contract, not a generic job-processing pattern.
Groniz's public API documents operations for listing integrations, finding the next slot, uploading media, and scheduling, listing, or deleting posts. Use those operations for the stage checks, and keep provider-specific settings tied to the live integration.
To build this recovery loop against the current contract, start with the Groniz Public API documentation.
Top comments (0)