pinpoint-apm/pinpoint · error · IllegalArgumentException
Invalid linkKey format: expected 'fromApp~toApp' but got:
Error message
Invalid linkKey format: expected 'fromApp~toApp' but got:
What it means
ServerMapHistogramController.getLinkTimeHistogramData validates the `linkKey` request parameter against the regex ^[^~]+~[^~]+$ before parsing it into a from/to application pair. This error is thrown when the supplied linkKey does not contain exactly two '~'-separated non-empty segments (e.g. it is empty, null-ish, or lacks the '~' separator). The controller refuses to proceed because it cannot split the key into fromApp and toApp applications.
Source
Thrown at web/src/main/java/com/navercorp/pinpoint/web/applicationmap/controller/ServerMapHistogramController.java:360
}
@GetMapping(value = "/statistics/links")
public LinkHistogramSummaryView getLinkTimeHistogramData(
@ServiceParam ServiceName serviceName,
@Valid @ModelAttribute
ApplicationForm appForm,
@Valid @ModelAttribute
RangeForm rangeForm,
@Valid @ModelAttribute
SearchOptionForm searchForm,
@RequestParam("linkKey") @NotBlank String linkKey
) {
final Range range = toRange(rangeForm);
this.rangeValidator.validate(range);
TimeWindow timeWindow = new TimeWindow(range);
if (!LINK_KEY_VALIDATION_PATTERN.matcher(linkKey).matches()) {
throw new IllegalArgumentException("Invalid linkKey format: expected 'fromApp~toApp' but got: " + linkKey);
}
String[] parts = LINK_DELIMITER_PATTERN.split(linkKey, 2);
if (parts.length != 2) {
throw new IllegalArgumentException("Invalid linkKey format: expected 'fromApp~toApp' but got: " + linkKey);
}
final Service service = serviceModelResolver.getService(serviceName.getName());
final Application fromApplication = this.newApplication(service, parts[0]);
final Application toApplication = this.newApplication(service, parts[1]);
final LinkHistogramSummary linkHistogramSummary =
histogramService.selectLinkHistogramData(fromApplication, toApplication, timeWindow);
return new LinkHistogramSummaryView(linkHistogramSummary, timeWindow, TimeHistogramView.TimeseriesHistogram);
}
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Pass the linkKey exactly as returned by the server-map data endpoint (format 'fromAppName~toAppName'), e.g. linkKey=FRONT~BACK
- Ensure the request actually includes the linkKey parameter; empty string fails the same validation
- Verify the two application names are non-empty and contain no '~' characters themselves; if an app name can contain '~', URL-encode it or pick a different delimiter path
- Check the client code that constructs the key — it must join exactly two non-empty segments with a single '~'
Example fix
// before
const linkKey = fromApp + toApp; // missing separator
const url = `/getLinkTimeHistogramData?linkKey=${linkKey}`;
// after
const linkKey = `${fromApp}~${toApp}`;
if (!fromApp || !toApp) throw new Error('fromApp and toApp are required');
const url = `/getLinkTimeHistogramData?linkKey=${encodeURIComponent(linkKey)}`; Defensive patterns
Strategy: validation
Validate before calling
function isValidLinkKey(linkKey) {
return typeof linkKey === 'string' && /^[^~]+~[^~]+$/.test(linkKey);
}
if (!isValidLinkKey(linkKey)) throw new Error('linkKey must be fromApp~toApp'); Type guard
function isLinkKey(v) {
return typeof v === 'string' && /^[^~]+~[^~]+$/.test(v);
} Try / catch
try {
const data = await api.getLinkTimeHistogramData({ linkKey });
} catch (e) {
if (e.status === 400 && String(e.message).includes('Invalid linkKey format')) {
// refresh linkKey from the server-map response and retry once
} else { throw e; }
} Prevention
- Always take linkKey values directly from server-map API responses instead of constructing them manually
- Validate the fromApp~toApp shape client-side before sending
- URL-encode link keys in query strings so '~' and special characters survive transit
- Guard against undefined/null link keys when UI state resets after map refreshes
When it happens
Trigger: GET/POST to the link time-histogram endpoint (getLinkTimeHistogramData) with a missing, empty, or malformed `linkKey` parameter — e.g. linkKey='', linkKey='myApp' (no '~'), or a key containing multiple '~' characters or empty sides like '~toApp' / 'fromApp~'.
Common situations: Frontend code building the link key by hand instead of using the node/link keys returned by the server-map API; URL-encoding issues that strip or mangle the '~'; a UI bug passing an undefined linkKey after a map refresh; API consumers guessing the key format instead of copying it verbatim from a previous server-map response.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Undefined service type
- there should be webhookSendInfoId to delete webhook
- There should be webhookSendInfoId, webhookId and ruleId to u
- hostName is empty
- Invalid time unit provided.
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/e433e1bdfb08638f.
Report an issue: GitHub.