Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
If Google Apps Script fails while converting HTML to PDF, first identify which stage failed: template evaluation, conversion to a PDF blob, or saving/emailing the result. For HTML generated by Apps Script, evaluate the template and convert the resulting HtmlOutput with getAs('application/pdf'). If you fetch an export URL instead, check authorization and the HTTP response before treating its body as a PDF. These are separate workflows, and a failure in one should not be diagnosed as though it occurred in another.
Trace the failure to the stage that produces it
A typical Apps Script PDF job has three stages. First, it builds or evaluates the HTML. Second, it converts the output into a blob with PDF content. Third, it saves, emails, or otherwise uses that blob. Log the stage and exact exception; a generic catch around the whole job can conceal whether the problem is a template error, a conversion limit, or a later Drive or mail operation.
- HTML creation: Did the template load, and did evaluation finish?
- Conversion: Did the evaluated output convert to a blob with the requested content type?
- Persistence or delivery: Did the save or email step fail after a blob was created?
Record a marker immediately before and after each operation. When a run stops, the last marker narrows the investigation. Avoid logging sensitive document contents; stage names, exception messages, response codes, and content types are usually more useful.
Evaluate an Apps Script HTML template before converting it
An Apps Script template containing server-side scriptlets is not yet an HtmlOutput. Call evaluate() to execute those scriptlets and produce the output object. This is server-side template evaluation, not execution of browser-side JavaScript after a page loads.
#1 Best Overall
- The Google Workspace Bible: [14 in 1] The Ultimate All in One Guide from Beginner to Advanced Including Gmail, Drive, Docs, Sheets, and Every Other App from the Suite
- ABIS BOOK
function makeInvoicePdf() {
const htmlOutput = HtmlService
.createTemplateFromFile('Invoice')
.evaluate();
const pdfBlob = htmlOutput
.getAs('application/pdf')
.setName('invoice.pdf');
return pdfBlob;
}
Here, Invoice is the template file name in the Apps Script project. The returned value is a blob that can then be passed to the appropriate Drive or email operation. Name the blob after conversion for clarity, but remember that a filename is metadata: a name ending in .pdf does not prove that the bytes are a valid PDF.
Inspect a template evaluation failure
If failure occurs before the conversion call, inspect the template and its server-side scriptlets. Apps Script provides getCode() and getCodeWithComments() on an HtmlTemplate; these expose the code generated from the template and can help locate malformed or unexpected scriptlet output. Google notes that errors in evaluated template code retain line correspondence with the original template. Check the original template around the reported line as well as the generated code.
Verify that the template file name is correct and that the data referenced by scriptlets exists when the template is evaluated. If the template expects values, assign them to the template object before calling evaluate(). Keep evaluation separate from conversion while debugging so an exception at one stage is not mistaken for an exception at the other.
Convert plain HTML or an evaluated output using the right method
For an evaluated template, use HtmlOutput.getAs('application/pdf'). Apps Script documents this method as returning the data in the output object as a blob converted to the specified content type; it also adds the appropriate file extension. Conversion quotas apply.
Rank #2
If you have an HTML string without Apps Script scriptlets, create an HtmlOutput from that content, then convert it. Inspect the content before converting:
function htmlStringToPdf(html) {
const output = HtmlService.createHtmlOutput(html);
Logger.log(output.getContent());
return output.getAs('application/pdf').setName('report.pdf');
}
createHtmlOutput can throw if the HTML is malformed. Validate the generated markup and values inserted into it; do not assume the PDF call is the first operation capable of failing. Logging the rendered HTML can help identify missing data or broken structure, but avoid writing private or sensitive content to logs.
Do not use Blob conversion as a repair step
Blob.getAs(contentType) is a documented conversion method, but it applies only when the input blob is a supported source for that conversion. It is not a universal way to turn arbitrary response bytes into a PDF. Use HtmlOutput.getAs('application/pdf') for the direct Apps Script HTML-output path. If a blob came from an HTTP request, check what the server actually returned before attempting to convert or save it.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
For URL Fetch workflows, verify authorization and the response
Some scripts retrieve a PDF from a service endpoint rather than converting an HtmlOutput. In that case, use UrlFetchApp deliberately: it requires the script.external_request authorization scope. A response body may be an error page or other non-PDF content, even if the script saves it with a .pdf name.
During diagnosis, set muteHttpExceptions: true so the request can return an HTTPResponse even when the server indicates failure. Inspect the status code, headers, and body before persisting the content. A successful-looking script execution is not enough to establish that the response is a PDF.
function fetchPdf(url) {
const response = UrlFetchApp.fetch(url, {
muteHttpExceptions: true
});
const status = response.getResponseCode();
const headers = response.getHeaders();
const contentType = headers['Content-Type'] || headers['content-type'] || '';
Logger.log('HTTP status: ' + status);
Logger.log('Content-Type: ' + contentType);
if (status < 200 || status >= 300) {
throw new Error('PDF request failed with HTTP status ' + status);
}
if (!String(contentType).toLowerCase().includes('pdf')) {
throw new Error('Expected a PDF response; received ' + contentType);
}
return response.getBlob().setName('report.pdf');
}
Use the response checks as diagnostics, not as a substitute for understanding the endpoint. Some services may use a different content-type convention, so confirm the expected response format for the specific endpoint. If the response is an HTML login page, authorization failure, or other error document, fix the request or permissions rather than saving those bytes as a PDF.
Use the Sheets export workflow only for spreadsheet-shaped reports
Google documents a separate pattern for creating PDFs from Google Sheets: populate a spreadsheet template, fetch its spreadsheet /export URL with UrlFetchApp, and store the returned PDF blob. The workflow is useful when the report can be represented and laid out in a sheet, such as an invoice or tabular report. It is not a general-purpose HTML renderer.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →| Decision point | Apps Script HTML output | Google Sheets export |
|---|---|---|
| Best fit | HTML assembled or evaluated by Apps Script | A report that can be represented in a spreadsheet template |
| Conversion route | HtmlOutput.getAs('application/pdf') |
Fetch the spreadsheet /export URL with UrlFetchApp |
| Checks to prioritize | Template evaluation, markup validity, conversion quota, output blob | Spreadsheet authorization, URL Fetch scope and response, quotas, export parameters |
| Scope | Documented HtmlOutput-to-blob conversion | Documented spreadsheet-template export example; not arbitrary HTML conversion |
For the Sheets route, follow the spreadsheet export pattern for authorization, export parameters, and the destination Drive folder. Inspect the fetched response before storing it, just as you would for any URL Fetch PDF workflow.
Rank #4
Check quotas and batch execution limits
PDF conversion, URL Fetch, and script execution are subject to quotas and limits. They depend on the account and can change; Google also warns that newly created Workspace domains may temporarily have stricter conversion quotas. Check the current Apps Script quotas documentation for the account running the script rather than relying on a number copied into an old example.
For a batch job, determine which limit applies before changing the implementation:
- Conversion quota: A failure at
getAs('application/pdf')can be quota-related. Check the applicable conversion quota for the account and whether the job runs under a new Workspace domain. - URL Fetch quota: A workflow that requests an export URL uses URL Fetch limits in addition to any conversion or spreadsheet constraints.
- Runtime and response size: Google’s quotas page lists execution duration and URL Fetch response-size limits. Large batches can hit these limits even if one document works.
- Batch strategy: Test a small batch, record the failing stage and item, and divide large work into manageable executions. Do not treat retries as a quota increase; repeated requests may consume more of a constrained allowance.
Google says quotas can change without notice. Treat the current quota page as authoritative for the account and service, particularly when a script recently began failing or runs under a different account than the one used during development.
Common failures and what to check
| Symptom | Likely stage | Practical check |
|---|---|---|
| Template-related exception or missing values | Template evaluation | Confirm the file name and data assignments; inspect generated template code and the original line indicated by the error. |
createHtmlOutput throws |
HTML construction | Validate the assembled markup and dynamic values before conversion. |
| Conversion call fails after evaluation | Output conversion | Confirm the receiver is an HtmlOutput, request application/pdf, and check conversion quotas. |
| Saved file has a PDF name but will not open | Response or blob handling | Check the actual content type and bytes; an extension does not make an error page into a PDF. |
| URL Fetch authorization error | HTTP retrieval | Authorize the script for external requests and verify the script.external_request scope. |
| Export fetch returns an error response | HTTP retrieval or export access | Enable muteHttpExceptions while debugging and inspect status and body; check the relevant spreadsheet authorization. |
| Small jobs work but batches stop | Quota or runtime | Check account-specific conversion, URL Fetch, execution-time, and response-size limits; process smaller batches. |
Screenshot a rendered web page instead of converting Apps Script HTML
Apps Script PDF conversion and website screenshot capture solve different problems. If your actual goal is to capture a public web page as an image or PDF—not to render an Apps Script template into a PDF blob—ScreenshotNeo is a separate option. ScreenshotNeo is a website screenshot API and MCP server for developers. Its capture options include PDF output, but it is not a replacement for debugging HtmlOutput.getAs() in an Apps Script workflow.
Best Value
Or skip the browser setup
For a website capture, one GET request can return an image or PDF. For example, this cURL request saves a WebP screenshot:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for the request parameters and PDF options. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots.
Learn about ScreenshotNeo or sign up free for 1,000 screenshots a month, with no card required.
Free tools Windows power users keep installed
One-click scans. No signup required.
Frequently Asked Questions
Does evaluate() run JavaScript in the browser?
No. It evaluates Apps Script template scriptlets on the server to produce an HtmlOutput; it is not a browser-rendering step.
Can I fix a failed conversion by renaming the output file to .pdf?
No. A filename extension does not validate or convert the file bytes.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

