yikart/AiToEarn · error · CustomErrorOrNull
ERR_CODE_OR_NULL
ERR_CODE_OR_NULL
Error message
PublishRecordNotFound
What it means
getByFlowId looks up the publish record for a publish flow by calling listByFlowId (local DB first, then relay records). If the returned list is empty — no record exists locally for (userId, flowId) and none came back from the relay — it throws AppException(ResponseCode.PublishRecordNotFound). This signals that no publish record is associated with the given flow ID for that user.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/publish/records/publish-record-read.service.ts:44
private readonly publishRecordRepo: PublishRecordRepository,
private readonly accountRepository: AccountRepository,
private readonly workService: WorkService,
@Optional() private readonly relayClientService?: RelayClientService,
) {}
async listByFlowId(userId: string, flowId: string) {
const localRecords = await this.publishRecordRepo.listByFlowIdAndUserId(flowId, userId)
if (localRecords.length > 0) {
return localRecords
}
return this.listRelayRecords(userId, '/v2/channels/publish/records', { flowId })
}
async getByFlowId(userId: string, flowId: string) {
const records = await this.listByFlowId(userId, flowId)
const record = records[0]
if (!record) {
throw new AppException(ResponseCode.PublishRecordNotFound)
}
return record
}
async listByUserId(userId: string, query?: {
accountId?: string
accountType?: AccountType
flowId?: string
source?: PublishRecordSource
status?: PublishStatus
type?: PublishType
time?: [Date, Date]
uid?: string
}) {
const localRecords = await this.publishRecordRepo.listByFilter({
userId,
...query,
})View on GitHub (pinned to d3aa8bea5b)
Solutions
- Verify the flowId is the one returned when the publish flow was created and belongs to the same user.
- List records via listByUserId/listByFlowId first to confirm the record exists before calling getByFlowId.
- Check that RelayClientService.enabled is true if records may live on the relay side.
- If the record should exist, inspect the publish_records collection for { userId, flowId } and re-run the publish flow if missing.
Example fix
// before
const record = await service.getByFlowId(userId, flowId)
// after
const records = await service.listByFlowId(userId, flowId)
if (!records.length) {
// handle gracefully: record not ready or unknown flowId
return null
}
const record = records[0] Defensive patterns
Strategy: validation
Validate before calling
const records = await service.listByFlowId(userId, flowId)
if (!records.length) throw new NotFoundError(`No publish record for flow ${flowId}`)
const record = records[0] Type guard
function hasRecord<T>(arr: T[]): arr is [T, ...T[]] {
return arr.length > 0
} Try / catch
try {
const record = await service.getByFlowId(userId, flowId)
} catch (e) {
if (e instanceof AppException && e.code === ResponseCode.PublishRecordNotFound) {
return null // flow not ready or unknown
}
throw e
} Prevention
- Store the flowId returned at publish-flow creation and reuse it verbatim.
- Check record existence with the list endpoint before the singular get.
- Keep the relay client enabled if your records may live on the relay.
- Never reuse flowIds across users or environments.
When it happens
Trigger: Calling getByFlowId with a flowId that never produced a publish record, a flowId belonging to a different userId, a typo'd/stale flowId, or relay disabled/unreachable while the record only exists on the relay side.
Common situations: Client polls publish status before the record has been created; the record was deleted after completion; multi-environment setups where the flow ran on the relay (aitoearn.ai/aitoearn.cn) but the local relay client is not enabled; copying a flowId from another environment.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/c8d7aae7775f39ec.
Report an issue: GitHub.