risingwavelabs/risingwave · error · MetaError
job {} not found in database
Error message
job {} not found in database What it means
get_job_fragments_by_id looks up the streaming job row by primary key in the meta database. If no row exists for `job_id`, it returns an anyhow error 'job {} not found in database', meaning the requested job id does not correspond to any persisted streaming job.
Source
Thrown at src/meta/src/controller/fragment.rs:651
&self,
job_id: JobId,
) -> MetaResult<(
StreamJobFragments,
HashMap<FragmentId, Vec<StreamActor>>,
HashMap<ActorId, PbActorStatus>,
)> {
let inner = self.inner.read().await;
// Load fragments matching the job from the database
let fragments: Vec<_> = FragmentModel::find()
.filter(fragment::Column::JobId.eq(job_id))
.all(&inner.db)
.await?;
let job_info = StreamingJob::find_by_id(job_id)
.one(&inner.db)
.await?
.ok_or_else(|| anyhow::anyhow!("job {} not found in database", job_id))?;
let fragment_actors =
self.collect_fragment_actor_pairs(fragments, job_info.stream_context())?;
let job_definition = resolve_streaming_job_definition(&inner.db, &HashSet::from([job_id]))
.await?
.remove(&job_id);
Self::compose_table_fragments(
job_id,
job_info.job_status.into(),
job_info.stream_context(),
fragment_actors,
job_info.max_parallelism as _,
job_definition,
)
}
View on GitHub (pinned to 6469eb736d)
Solutions
- Confirm the job exists: SELECT ... FROM streaming_job WHERE job_id = <id> in the meta DB, or SHOW MATERIALIZED VIEWS
- Refresh any cached job id in the client and re-resolve the job by name
- Handle the not-found error gracefully on the caller side (e.g. return a 404-equivalent rather than surfacing it as an internal error)
- If the job should exist, check meta node logs for a drop job around the failure time
Example fix
// before
let job = StreamingJob::find_by_id(job_id).one(&inner.db).await?.ok_or_else(|| anyhow!("job {} not found", job_id))?;
// after
match StreamingJob::find_by_id(job_id).one(&inner.db).await? {
Some(job) => job,
None => return Err(MetaError::catalog(JobNotFound::new(job_id).into())),
} Defensive patterns
Strategy: validation
Validate before calling
let exists = StreamingJob::find_by_id(job_id).one(&db).await?.is_some();
if !exists { return Err(not_found()); } Try / catch
match get_job_fragments_by_id(job_id).await { Ok(f) => f, Err(e) if e.to_string().contains("not found in database") => handle_job_gone(job_id), Err(e) => return Err(e) } Prevention
- Re-resolve job ids by name before API calls instead of caching them
- Handle job-dropped races explicitly in polling callers
- Validate job ids against the catalog before querying
When it happens
Trigger: Calling FragmentManager::get_job_fragments_by_id with a job_id that was already dropped, never created, or a table/system id that is not a streaming job row.
Common situations: Race between a client fetching job fragments and a DROP MATERIALIZED VIEW completing; stale job id cached in the frontend after the job was removed; using a table id from another environment's meta store.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- database {} not found when resolving reschedule intent
- database {} unavailable {}
- value {:?} out of range, expect {:?}
- cannot find subscription with id {}
- failed to find fragment: {}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/485aab13311ae615.
Report an issue: GitHub.