A SharePoint integration can return HTTP 200 and still be completely wrong. That is one of the most annoying failures to troubleshoot: the request succeeded, but the list is empty, the wrong site was resolved, or Graph returned a different field shape than expected.
The problem: “successful” responses that contain bad data
Imagine a directory job that normally returns 850 employees. Today it returns 0 and still writes a new public file. The web server is healthy, authentication worked, and the JSON is valid—so a basic uptime check reports success.
{
"status": 200,
"value": []
}
The quirk: transport success is not business success
I troubleshoot the request in layers: network, authentication, source selection, response shape, normalization, and output. That keeps me from changing three things at once and losing the original evidence.
$started = microtime(true);
$response = callMicrosoftGraph();
$data = json_decode($response, true);
if (!is_array($data) || !isset($data['value'])) {
throw new RuntimeException('Unexpected Graph response shape');
}
$count = count($data['value']);
error_log(json_encode([
'sourceCount' => $count,
'durationMs' => round((microtime(true) - $started) * 1000)
]));
The workaround: add a sanity check before output
if ($count < 500) {
throw new RuntimeException(
"Employee count dropped to {$count}; previous output preserved."
);
}
I also log safe identifiers such as the site key, list key, record count, and duration—but never tokens or full personnel records. AI is useful for comparing logs and suggesting branches to test. The reliable part is still the diagnostic discipline: test one boundary, preserve the evidence, and do not publish until the data passes a business-level check.
