ToolsJobFailedPayload tools.job.failed@1
Generated at from
openvibe-contracts v0.33.0 and
openvibe-sdk v0.5.0.
- Version
- 1.0.0
- Owner
- tools
- Visibility
- first-party
- Status
- active
- Compatibility
- backward
- Schema
https://openvibe.network/contracts/events/payloads/tools.job.failed.v1.json
tools.job.failed v1 (OpenVibe.Tools apps/_shared/jobs/events.js). The job failed: the tool refused the input, it timed out, or it was running when the satellite restarted and its type does not requeue. A cancelled job is not a failure and is not announced as one. Emitted in the transaction that records the transition, beside the job's own SSE event. Carries ids, type, owner, state, times and result locations; never the job's input, its files, its output data or a session. Jobs of sandbox app tokens are not announced. Envelope: subject { type: job, id: <job_id> }, visibility internal, priority important, actor service:tools.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
job_id | string | yes |
| |
service | string | yes | The Tools satellite that runs the job (img, audio, docs…). |
|
type | string | yes | Job type, e.g. img.process. |
|
type_version | integer | yes |
| |
state | const | yes |
| |
owner | one of | yes | Who submitted the job: a user (user:usr_…), a service, app or mod principal. null for an anonymous browser session; the session is never published. | |
attempts | integer | yes |
| |
max_attempts | integer | yes |
| |
created_at | string | yes |
| |
retry_of | string | null | yes | The failed job this one retries (POST /api/v1/jobs/:id/retry). |
|
started_at | string | null | yes | null when the job failed before it ever ran. |
|
finished_at | string | yes |
| |
expires_at | string | null | yes | When the job and its result files are pruned; null while something references the result (PUT /api/v1/jobs/:id/references/:ref). |
|
error | object | yes | The job's problem (errors.problem@1) without request or trace ids. |
|
error.status | integer | yes |
| |
error.code | string | yes | tools.job.failed, tools.job.timeout, or a code the tool chose (tools.…). |
|
error.detail | string | yes | Human-readable reason; server paths are scrubbed. |
|
retryable | boolean | yes |
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: timeout
{
"job_id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"service": "img",
"type": "img.process",
"type_version": 1,
"state": "failed",
"owner": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR"
},
"attempts": 3,
"max_attempts": 3,
"created_at": "2026-09-23T09:00:00.000Z",
"retry_of": null,
"started_at": "2026-09-23T09:00:01.000Z",
"finished_at": "2026-09-23T09:10:01.000Z",
"expires_at": "2026-09-23T10:10:01.000Z",
"error": {
"status": 504,
"code": "tools.job.timeout",
"detail": "The job ran longer than 600 s"
},
"retryable": true
}Rejected: foreign-code
{
"job_id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"service": "img",
"type": "img.process",
"type_version": 1,
"state": "failed",
"owner": null,
"attempts": 1,
"max_attempts": 3,
"created_at": "2026-09-23T09:00:00.000Z",
"retry_of": null,
"started_at": null,
"finished_at": "2026-09-23T09:00:02.000Z",
"expires_at": "2026-09-23T10:00:02.000Z",
"error": {
"status": 500,
"code": "ENOENT",
"detail": "no such file"
},
"retryable": false
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('tools.job.failed@1', value); // { valid, errors: [{ path, message }] }