{"record":{"id":"a71df4d1261cd103","repo":"louislam/uptime-kuma","slug":"failed-to-create-measurement-this-formatapierro","errorCode":null,"errorMessage":"Failed to create measurement: ${this.formatApiError(res.data.error)}","messagePattern":"Failed to create measurement: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/monitor-types/globalping.js","lineNumber":102,"sourceCode":"        if (monitor.ipFamily === \"ipv4\") {\n            opts.measurementOptions.ipVersion = IpVersion[4];\n        } else if (monitor.ipFamily === \"ipv6\") {\n            opts.measurementOptions.ipVersion = IpVersion[6];\n        }\n\n        log.debug(\"monitor\", `Globalping create measurement: ${JSON.stringify(opts)}`);\n        let res = await client.createMeasurement(opts);\n\n        // Retry if the server returns a 500 error\n        if (!res.ok && Globalping.isHttpStatus(500, res)) {\n            res = await client.createMeasurement(opts);\n        }\n\n        if (!res.ok) {\n            if (Globalping.isHttpStatus(429, res)) {\n                throw new Error(`Failed to create measurement: ${this.formatTooManyRequestsError(hasAPIToken)}`);\n            }\n            throw new Error(`Failed to create measurement: ${this.formatApiError(res.data.error)}`);\n        }\n\n        log.debug(\"monitor\", `Globalping fetch measurement: ${res.data.id}`);\n        let measurement = await client.awaitMeasurement(res.data.id);\n\n        if (!measurement.ok) {\n            throw new Error(\n                `Failed to fetch measurement (${res.data.id}): ${this.formatApiError(measurement.data.error)}`\n            );\n        }\n\n        const probe = measurement.data.results[0].probe;\n        const result = measurement.data.results[0].result;\n\n        if (result.status === \"failed\") {\n            throw new Error(this.formatResponse(probe, `Failed: ${result.rawOutput}`));\n        }\n","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/monitor-types/globalping.js#L84-L120","documentation":"Thrown by the Globalping monitor when createMeasurement returns a non-ok, non-429, non-500 response. formatApiError renders the Globalping error object as \"<type> <message>.\\n<param>: <value>...\". A single 500 is auto-retried before this throw; anything else (400 validation, 401/403 auth, 404, 5xx that persisted) lands here.","triggerScenarios":"Submit a measurement with an invalid target/protocol/location/port combo (400), an expired or invalid API token (401/403), an unknown location magic string, or hit a Globalping outage returning 502/503 that the 500-retry did not cover.","commonSituations":"Wrong protocol for the measurement type (e.g. TCP without a port, set via monitor.protocol/port), unsupported location string, stale API token, Globalping maintenance window, breaking API change after a version bump.","solutions":["Read the embedded <type> and <message>: validation errors name the offending field.","For 401/403, refresh or re-enter the Globalping API token in settings.","For location errors, use a known magic location (e.g. a region or 'magic+ww' style) from Globalping docs.","For 5xx that is not 500, treat as transient and retry after a short delay; check status.globalping.io."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function validateMeasurementInput(monitor) {\n  if (monitor.protocol === \"TCP\" && !monitor.port) throw new Error(\"TCP measurements require a port\");\n  if (!monitor.hostname) throw new Error(\"hostname is required\");\n  return true;\n}","typeGuard":"function isPlausibleGlobalpingTarget(monitor) {\n  return Boolean(monitor?.hostname) && (monitor.protocol !== \"TCP\" || Number.isFinite(Number(monitor?.port)));\n}","tryCatchPattern":"try {\n  await gp.monitor(client, monitor, heartbeat, hasToken);\n} catch (e) {\n  if (/Failed to create measurement/.test(e.message) && !/run out of credits/.test(e.message)) {\n    heartbeat.status = DOWN; heartbeat.msg = e.message; return;\n  }\n  throw e;\n}","preventionTips":["Validate target/protocol/port combos before sending to Globalping.","Keep the API token current; rotate before expiry."],"tags":["globalping","api","validation","uptime-kuma"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}