{"record":{"id":"4a75598c1ab11250","repo":"Dolibarr/dolibarr","slug":"errordownloaddocumenthooks-errors","errorCode":null,"errorMessage":"ErrorDownloadDocumentHooks: ${errors}","messagePattern":"ErrorDownloadDocumentHooks: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"htdocs/document.php","lineNumber":370,"sourceCode":"\n// This test if file exists should be useless. We keep it to find bug more easily\nif (!file_exists($fullpath_original_file_osencoded)) {\n\tdol_syslog(\"ErrorFileDoesNotExists: \".$fullpath_original_file);\n\tprint $langs->trans(\"ErrorFileDoesNotExists\") . ' : ' . dol_escape_htmltag($original_file);\n\texit;\n}\n\n// Hooks\n$hookmanager->initHooks(array('document'));\n$parameters = array('ecmfile' => $ecmfile, 'modulepart' => $modulepart, 'original_file' => $original_file,\n\t'entity' => $entity, 'fullpath_original_file' => $fullpath_original_file,\n\t'filename' => $filename, 'fullpath_original_file_osencoded' => $fullpath_original_file_osencoded);\n$object = new stdClass();\n$reshook = $hookmanager->executeHooks('downloadDocument', $parameters, $object, $action); // Note that $action and $object may have been\nif ($reshook < 0) {\n\t$errors = $hookmanager->error.(is_array($hookmanager->errors) ? (!empty($hookmanager->error) ? ', ' : '').implode(', ', $hookmanager->errors) : '');\n\tdol_syslog(\"document.php - Errors when executing the hook 'downloadDocument' : \".$errors);\n\tprint \"ErrorDownloadDocumentHooks: \".$errors;\n\texit;\n}\n\n// Set this for test\n//$type = 'text/html'; $attachment = -1;\n\n\n// If we show an invoice, we test if we must regenerate the PDF\nif ($modulepart == 'facture') {\n\t$refname = basename(dirname($original_file).\"/\");\n\tif ($refname == 'thumbs' || $refname == 'temp') {\n\t\t// If we get the thumbs directory, we must go one step higher. For example original_file='10/thumbs/myfile_small.jpg' -> refname='10'\n\t\t$refname = basename(dirname(dirname($original_file)).\"/\");\n\t}\n\n\t$invoice = fetchObjectByElement(0, $modulepart, $refname);\n\n\tif ($original_file == preg_replace('/facture\\//', '', $invoice->last_main_doc)) {","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/Dolibarr/dolibarr/blob/598aa4bdada683d17ca04b1842548821ff0eb6c6/htdocs/document.php#L352-L388","documentation":"When a module's 'downloadDocument' hook returns a negative reshook, document.php aggregates $hookmanager->error and $hookmanager->errors, prints 'ErrorDownloadDocumentHooks: <errors>' and aborts the download. It surfaces hook-side rejection of a file download from htdocs/document.php:366-372.","triggerScenarios":"A module implementing hook downloadDocument (e.g. an encryption, antivirus, or access-control module) returns -1 and populates $hookmanager->error or $hookmanager->errors while a user downloads a document through document.php.","commonSituations":"Antivirus/encryption modules failing to decrypt or scan the file; custom permission modules denying access; a hook throwing errors after a module upgrade changed its API; hook code setting ->errors as a string instead of an array.","solutions":["Read the printed error list to identify which module's hook failed","Check that module's downloadDocument hook implementation and its log/messages","Update or disable the third-party module causing the negative reshook","In your own hook, set $this->errors = array($msg) (an array) and return -1 only on real failures"],"exampleFix":"// before (hook)\n$this->error = 'Cannot decrypt';\nreturn -1;\n// after\n$this->errors = array('Cannot decrypt file '.$parameters['filename']);\nreturn -1;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"$reshook = $hookmanager->executeHooks('downloadDocument', $parameters, $object, $action);\nif ($reshook < 0) {\n    setEventMessages('Download blocked by hook: '.(is_array($hookmanager->errors) ? implode(', ', $hookmanager->errors) : $hookmanager->error), null, 'errors');\n}","preventionTips":["In hooks, always set $this->errors as an array and return -1 only on real failures","Test download flows with all third-party modules enabled after upgrades","Log hook errors with dol_syslog for diagnosis","Review module compatibility notes before enabling access-control or AV hooks"],"tags":["hooks","file-download","third-party-module","dolibarr"],"backgroundTag":"api-error-response","analyzedSha":"598aa4bdada683d17ca04b1842548821ff0eb6c6","analyzedAt":"2026-09-14T11:12:15.309Z","contentChangedAt":"2026-09-14T11:12:15.309Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}