Crosstalk-Solutions/project-nomad · warning

Service ${params.name} not found

Error message

Service ${params.name} not found

What it means

HTTP 404 from getServiceLogs when no Service row matches the service_name route param. The endpoint is scoped to managed services so arbitrary sibling containers (admin app, database) are not readable by name.

Source

Thrown at admin/app/controllers/system_controller.ts:559

            return response.status(403).send({ success: false, message: 'Only custom apps can be updated this way.' })
        }

        const result = await this.dockerService.recreateCustomAppContainer(payload.service_name, {
            forcePull: true,
        })
        if (result.success) {
            return response.send({ success: true, message: result.message })
        }
        return response.status(400).send({ success: false, message: result.message })
    }

    /** Return the last N lines of a service container's logs. */
    async getServiceLogs({ params, request, response }: HttpContext) {
        // Scope to managed services only — otherwise any sibling container's logs (admin app,
        // database) would be readable by name on this unauthenticated API surface.
        const service = await Service.query().where('service_name', params.name).first()
        if (!service) {
            return response.status(404).send({ success: false, message: `Service ${params.name} not found` })
        }
        const { tail } = await request.validateUsing(serviceLogsValidator)
        const result = await this.dockerService.getContainerLogs(params.name, tail ?? 200)
        if (!result.success) {
            return response.status(404).send({ success: false, message: result.message })
        }
        return response.send({ success: true, logs: result.logs })
    }

    /** Return a one-shot CPU/memory usage snapshot for a running service container. */
    async getServiceStats({ params, response }: HttpContext) {
        // Scope to managed services only (see getServiceLogs).
        const service = await Service.query().where('service_name', params.name).first()
        if (!service) {
            return response.status(404).send({ success: false, message: `Service ${params.name} not found` })
        }
        const result = await this.dockerService.getContainerStats(params.name)
        if (!result.success) {

View on GitHub (pinned to 0bd1c6f4f9)

Solutions

  1. List services via the services index endpoint and use the exact service_name
  2. If the service should exist, re-run its installer/registration
  3. Do not attempt to read infra containers (database, admin) through this route
Defensive patterns

Strategy: validation

Validate before calling

const services = await api.listServices()
if (!services.some((s) => s.service_name === name)) return notFound()

Try / catch

try { await getLogs(name) } catch (e: any) { if (e.status === 404) show('Unknown service') else throw e }

Prevention

When it happens

Trigger: GET /services/:name/logs where :name is not a row in the services table — typo'd name, unmanaged container name like the postgres container, or a service not yet registered.

Common situations: Guessing the docker container name instead of the registered service_name; querying logs of infrastructure containers; stale frontend cached name after a service was removed.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27). Data as JSON: /api/errors/0a1142b881812731. Report an issue: GitHub.