Index: /trunk/psModules/src/objects/pmPSF_IO.c
===================================================================
--- /trunk/psModules/src/objects/pmPSF_IO.c	(revision 27176)
+++ /trunk/psModules/src/objects/pmPSF_IO.c	(revision 27177)
@@ -122,5 +122,5 @@
     if (view->chip == -1) {
         if (!pmPSFmodelWriteFPA(fpa, view, file, config)) {
-            psError(PS_ERR_IO, false, "Failed to write PSF for fpa");
+            psError(psErrorCodeLast(), false, "Failed to write PSF for fpa");
             return false;
         }
@@ -135,5 +135,5 @@
     if (view->cell == -1) {
         if (!pmPSFmodelWriteChip (chip, view, file, config)) {
-            psError(PS_ERR_IO, false, "Failed to write PSF for chip");
+            psError(psErrorCodeLast(), false, "Failed to write PSF for chip");
             return false;
         }
@@ -141,5 +141,5 @@
     }
 
-    psError(PS_ERR_IO, false, "PSF must be written at the chip level");
+    psError(PM_ERR_CONFIG, true, "PSF must be written at the chip level");
     return false;
 }
@@ -158,5 +158,5 @@
         thisView->chip = i;
         if (!pmPSFmodelWriteChip (chip, thisView, file, config)) {
-            psError(PS_ERR_IO, false, "Failed to write PSF for %dth chip", i);
+            psError(psErrorCodeLast(), false, "Failed to write PSF for %dth chip", i);
             psFree(thisView);
             return false;
@@ -173,6 +173,6 @@
     PS_ASSERT_PTR_NON_NULL(chip, false);
 
-    if (!pmPSFmodelWrite (chip->analysis, view, file, config)) {
-        psError(PS_ERR_IO, false, "Failed to write PSF for chip");
+    if (!pmPSFmodelWrite(chip->analysis, view, file, config)) {
+        psError(psErrorCodeLast(), false, "Failed to write PSF for chip");
         return false;
     }
@@ -197,10 +197,13 @@
     char *headName, *tableName, *residName;
 
-    if (!analysis) return false;
+    if (!analysis) {
+        psError(PM_ERR_PROG, true, "No analysis metadata for chip.");
+        return false;
+    }
 
     // select the current recipe
     psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, "PSPHOT");
     if (!recipe) {
-        psError(PS_ERR_UNKNOWN, false, "missing recipe %s", "PSPHOT");
+        psError(PM_ERR_CONFIG, false, "missing recipe %s", "PSPHOT");
         return false;
     }
@@ -213,8 +216,12 @@
     // get the current header
     pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false); // Suitable FPA for writing
+    if (!fpa) {
+        psError(psErrorCodeLast(), false, "Unable to get FPA for writing.");
+        return false;
+    }
     pmHDU *hdu = psMemIncrRefCounter(pmFPAviewThisHDU(view, fpa));
     psFree(fpa);
     if (!hdu) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to find HDU");
+        psError(PM_ERR_CONFIG, false, "Unable to find HDU");
         return false;
     }
@@ -234,5 +241,5 @@
         psMetadata *menu = psMetadataLookupMetadata(&status, file->camera, "EXTNAME.RULES");
         if (!menu) {
-            psError(PS_ERR_UNKNOWN, true, "missing EXTNAME.RULES in camera.config");
+            psError(PM_ERR_CONFIG, true, "missing EXTNAME.RULES in camera.config");
             psFree(hdu);
             return false;
@@ -242,5 +249,5 @@
         rule = psMetadataLookupStr(&status, menu, "PSF.HEAD");
         if (!rule) {
-            psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.HEAD in EXTNAME.RULES in camera.config");
+            psError(PM_ERR_CONFIG, false, "missing entry for PSF.HEAD in EXTNAME.RULES in camera.config");
             psFree(hdu);
             return false;
@@ -251,5 +258,5 @@
         rule = psMetadataLookupStr(&status, menu, "PSF.TABLE");
         if (!rule) {
-            psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.TABLE in EXTNAME.RULES in camera.config");
+            psError(PM_ERR_CONFIG, false, "missing entry for PSF.TABLE in EXTNAME.RULES in camera.config");
             psFree (headName);
             psFree(hdu);
@@ -261,5 +268,5 @@
         rule = psMetadataLookupStr(&status, menu, "PSF.RESID");
         if (!rule) {
-            psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.RESID in EXTNAME.RULES in camera.config");
+            psError(PM_ERR_CONFIG, false, "missing entry for PSF.RESID in EXTNAME.RULES in camera.config");
             psFree (headName);
             psFree (tableName);
@@ -294,5 +301,9 @@
         }
 
-        psFitsWriteBlank (file->fits, hdu->header, headName);
+        if (!psFitsWriteBlank(file->fits, hdu->header, headName)) {
+            psError(psErrorCodeLast(), false, "Unable to write PSF PHU.");
+            psFree(hdu);
+            return false;
+        }
         psTrace ("pmFPAfile", 5, "wrote ext head %s (type: %d)\n", file->filename, file->type);
         file->header = hdu->header;
@@ -304,5 +315,5 @@
     pmPSF *psf = psMetadataLookupPtr (&status, analysis, "PSPHOT.PSF");
     if (!psf) {
-        psError(PS_ERR_UNKNOWN, true, "missing PSF for this analysis metadata");
+        psError(PM_ERR_PROG, true, "missing PSF for this analysis metadata");
         psFree (tableName);
         psFree (residName);
@@ -322,5 +333,5 @@
         psMetadataAddBool (header, PS_LIST_TAIL, "ERR_PAR",  0, "Use Poisson errors in fits?", psf->poissonErrorsParams);
 
-        int nPar = pmModelClassParameterCount (psf->type)    ;
+        int nPar = pmModelClassParameterCount (psf->type);
         psMetadataAdd (header, PS_LIST_TAIL, "PSF_NPAR", PS_DATA_S32, "PSF model parameter count", nPar);
 
@@ -436,10 +447,14 @@
         // write an empty FITS segment if we have no PSF information
         if (psfTable->n == 0) {
-            // XXX this is probably an error (if we have a PSF, how do we have no data?)
-            psFitsWriteBlank (file->fits, header, tableName);
+            psError(PM_ERR_PROG, true, "No PSF data to write.");
+            psFree(tableName);
+            psFree(residName);
+            psFree(psfTable);
+            psFree(header);
+            return false;
         } else {
             psTrace ("pmFPAfile", 5, "writing psf data %s\n", tableName);
-            if (!psFitsWriteTable (file->fits, header, psfTable, tableName)) {
-                psError(PS_ERR_IO, false, "writing psf table data %s\n", tableName);
+            if (!psFitsWriteTable(file->fits, header, psfTable, tableName)) {
+                psError(psErrorCodeLast(), false, "Error writing psf table data %s\n", tableName);
                 psFree (tableName);
                 psFree (residName);
@@ -459,5 +474,10 @@
         if (psf->residuals == NULL) {
             // set some header keywords to make it clear there are no residuals?
-            psFitsWriteBlank (file->fits, header, residName);
+            if (!psFitsWriteBlank(file->fits, header, residName)) {
+                psError(psErrorCodeLast(), false, "Unable to write blank PSF residual image.");
+                psFree(residName);
+                psFree(header);
+                return false;
+            }
             psFree (residName);
             psFree (header);
@@ -479,9 +499,21 @@
             psArrayAdd (images, 1, psf->residuals->Ry);
 
-            psFitsWriteImageCube (file->fits, header, images, residName);
+            if (!psFitsWriteImageCube (file->fits, header, images, residName)) {
+                psError(psErrorCodeLast(), false, "Unable to write PSF residuals.");
+                psFree(images);
+                psFree(residName);
+                psFree(header);
+                return false;
+            }
             psFree (images);
         } else {
             // this call creates an extension with NAXIS3 = 1
-            psFitsWriteImage(file->fits, header, psf->residuals->Ro, 0, residName);
+            if (!psFitsWriteImage(file->fits, header, psf->residuals->Ro, 0, residName)) {
+                psError(psErrorCodeLast(), false, "Unable to write PSF residuals.");
+                psFree(images);
+                psFree(residName);
+                psFree(header);
+                return false;
+            }
         }
         psFree (residName);
@@ -495,5 +527,10 @@
         if (0) {
             // set some header keywords to make it clear there are no residuals?
-            psFitsWriteBlank (file->fits, header, residName);
+            if (!psFitsWriteBlank (file->fits, header, residName)) {
+                psError(psErrorCodeLast(), false, "Unable to write blank PSF residuals.");
+                psFree(residName);
+                psFree(header);
+                return false;
+            }
             psFree (residName);
             psFree (header);
@@ -501,45 +538,58 @@
         }
 
-	int DX = 65;
-	int DY = 65;
-
-	psImage *psfMosaic = psImageAlloc (DX, DY, PS_TYPE_F32);
-	psImageInit (psfMosaic, 0.0);
-
-	pmModel *modelRef = pmModelAlloc(psf->type);
-
-	// use the center of the center pixel of the image
-	float xc = 0.5*psf->fieldNx;
-	float yc = 0.5*psf->fieldNy;
-
-	// assign the x and y coords to the image center
-	// create an object with center intensity of 1000
-	modelRef->params->data.F32[PM_PAR_SKY] = 0;
-	modelRef->params->data.F32[PM_PAR_I0] = 1.000;
-	modelRef->params->data.F32[PM_PAR_XPOS] = xc;
-	modelRef->params->data.F32[PM_PAR_YPOS] = yc;
-
-	// create modelPSF from this model
-	pmModel *model = pmModelFromPSF (modelRef, psf);
-	if (model) {
-	    // place the reference object in the image center
-	    pmModelAddWithOffset (psfMosaic, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_CENTER, 0, 0.0, 0.0);
-	    psFree (model);
-	
-	    if (false) {
-		// this call creates an extension with NAXIS3 = 3
-		psArray *images = psArrayAllocEmpty (3);
-		psArrayAdd (images, 1, psfMosaic);
-		// psArrayAdd (images, 1, psfModel);
-		// psArrayAdd (images, 1, psfModel);
-
-		psFitsWriteImageCube (file->fits, header, images, "PSF_MODEL");
-		psFree (images);
-	    } else {
-		// this call creates an extension with NAXIS3 = 1
-		// XXX need to replace PSF_MODEL with rule-based name like residName
-		psFitsWriteImage(file->fits, header, psfMosaic, 0, "PSF_MODEL");
-	    }
-	}
+        int DX = 65;
+        int DY = 65;
+
+        psImage *psfMosaic = psImageAlloc (DX, DY, PS_TYPE_F32);
+        psImageInit (psfMosaic, 0.0);
+
+        pmModel *modelRef = pmModelAlloc(psf->type);
+
+        // use the center of the center pixel of the image
+        float xc = 0.5*psf->fieldNx;
+        float yc = 0.5*psf->fieldNy;
+
+        // assign the x and y coords to the image center
+        // create an object with center intensity of 1000
+        modelRef->params->data.F32[PM_PAR_SKY] = 0;
+        modelRef->params->data.F32[PM_PAR_I0] = 1.000;
+        modelRef->params->data.F32[PM_PAR_XPOS] = xc;
+        modelRef->params->data.F32[PM_PAR_YPOS] = yc;
+
+        // create modelPSF from this model
+        pmModel *model = pmModelFromPSF (modelRef, psf);
+        if (model) {
+            // place the reference object in the image center
+            pmModelAddWithOffset (psfMosaic, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_CENTER, 0, 0.0, 0.0);
+            psFree (model);
+
+            if (false) {
+                // this call creates an extension with NAXIS3 = 3
+                psArray *images = psArrayAllocEmpty (3);
+                psArrayAdd (images, 1, psfMosaic);
+                // psArrayAdd (images, 1, psfModel);
+                // psArrayAdd (images, 1, psfModel);
+
+                if (!psFitsWriteImageCube (file->fits, header, images, "PSF_MODEL")) {
+                    psError(psErrorCodeLast(), false, "Unable to write PSF representation.");
+                    psFree(images);
+                    psFree(psfMosaic);
+                    psFree(modelRef);
+                    psFree(header);
+                    return false;
+                }
+                psFree (images);
+            } else {
+                // this call creates an extension with NAXIS3 = 1
+                // XXX need to replace PSF_MODEL with rule-based name like residName
+                if (!psFitsWriteImage(file->fits, header, psfMosaic, 0, "PSF_MODEL")) {
+                    psError(psErrorCodeLast(), false, "Unable to write PSF representation.");
+                    psFree(psfMosaic);
+                    psFree(modelRef);
+                    psFree(header);
+                    return false;
+                }
+            }
+        }
 
         psFree (psfMosaic);
@@ -594,4 +644,8 @@
     // find the FPA phu
     pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false); // Suitable FPA for writing
+    if (!fpa) {
+        psError(psErrorCodeLast(), false, "Unable to build FPA to write.");
+        return false;
+    }
     pmHDU *phu = psMemIncrRefCounter(pmFPAviewThisPHU(view, fpa));
     psFree(fpa);
@@ -604,10 +658,18 @@
         psMetadataCopy (outhead, phu->header);
     } else {
-        pmConfigConformHeader (outhead, file->format);
+        if (!pmConfigConformHeader (outhead, file->format)) {
+            psError(psErrorCodeLast(), false, "Unable to conform header of PSF PHU.");
+            psFree(phu);
+            return false;
+        }
     }
     psFree(phu);
 
     psMetadataAddBool (outhead, PS_LIST_TAIL, "EXTEND", PS_META_REPLACE, "this file has extensions", true);
-    psFitsWriteBlank (file->fits, outhead, "");
+    if (!psFitsWriteBlank (file->fits, outhead, "")) {
+        psError(psErrorCodeLast(), false, "Unable to write PHU for PSF.");
+        psFree(outhead);
+        return false;
+    }
     file->wrote_phu = true;
 
@@ -639,5 +701,5 @@
     }
 
-    psError(PS_ERR_IO, false, "PSF must be read at the chip level");
+    psError(PM_ERR_CONFIG, true, "PSF must be read at the chip level");
     return false;
 }
@@ -666,5 +728,5 @@
 
     if (!pmPSFmodelRead (chip->analysis, view, file, config)) {
-        psError(PS_ERR_IO, false, "Failed to write PSF for chip");
+        psError(psErrorCodeLast(), false, "Failed to write PSF for chip");
         return false;
     }
@@ -689,5 +751,5 @@
     psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, "PSPHOT");
     if (!recipe) {
-        psError(PS_ERR_UNKNOWN, false, "missing recipe %s", "PSPHOT");
+        psError(PM_ERR_CONFIG, false, "missing recipe %s", "PSPHOT");
         return false;
     }
@@ -696,5 +758,5 @@
     psMetadata *menu = psMetadataLookupMetadata(&status, file->camera, "EXTNAME.RULES");
     if (!menu) {
-        psError(PS_ERR_UNKNOWN, true, "missing EXTNAME.RULES in camera.config");
+        psError(PM_ERR_CONFIG, true, "missing EXTNAME.RULES in camera.config");
         return false;
     }
@@ -702,5 +764,5 @@
     rule = psMetadataLookupStr(&status, menu, "PSF.TABLE");
     if (!rule) {
-        psError(PS_ERR_UNKNOWN, true, "missing entry for PSF.TABLE in EXTNAME.RULES in camera.config");
+        psError(PM_ERR_CONFIG, true, "missing entry for PSF.TABLE in EXTNAME.RULES in camera.config");
         return false;
     }
@@ -709,5 +771,5 @@
     rule = psMetadataLookupStr(&status, menu, "PSF.RESID");
     if (!rule) {
-        psError(PS_ERR_UNKNOWN, true, "missing entry for PSF.RESID in EXTNAME.RULES in camera.config");
+        psError(PM_ERR_CONFIG, true, "missing entry for PSF.RESID in EXTNAME.RULES in camera.config");
         return false;
     }
@@ -717,11 +779,15 @@
     // advance to the table data extension
     // since we have read the IMAGE header, the TABLE header should exist
-    if (!psFitsMoveExtName (file->fits, tableName)) {
-        psAbort("cannot find data extension %s in %s", tableName, file->filename);
+    if (!psFitsMoveExtName(file->fits, tableName)) {
+        psError(psErrorCodeLast(), false, "cannot find data extension %s in %s", tableName, file->filename);
+        return false;
     }
 
     // load the PSF model table header
     header = psFitsReadHeader (NULL, file->fits);
-    if (!header) psAbort("cannot read table header");
+    if (!header) {
+        psError(psErrorCodeLast(), false, "Cannot read PSF table header.");
+        return false;
+    }
 
     pmPSFOptions *options = pmPSFOptionsAlloc();
@@ -835,5 +901,5 @@
         char *modeName = psMetadataLookupStr (&status, header, name);
         if (!status) {
-            psError(PS_ERR_UNKNOWN, true, "inconsistent PSF header: NX & NY defined for PAR %d, but not MD", i);
+            psError(PM_ERR_IO, true, "inconsistent PSF header: NX & NY defined for PAR %d, but not MD", i);
             return false;
         }
@@ -869,4 +935,9 @@
     // read the raw table data
     psArray *table = psFitsReadTable (file->fits);
+    if (!table) {
+        psError(psErrorCodeLast(), false, "Unable to read PSF table.");
+        psFree(header);
+        return false;
+    }
 
     // fill in the matching psf->params entries
@@ -913,8 +984,14 @@
     // since we have read the IMAGE header, the TABLE header should exist
     if (!psFitsMoveExtName (file->fits, imageName)) {
-        psAbort("cannot find data extension %s in %s", imageName, file->filename);
+        psError(psErrorCodeLast(), false, "Cannot find PSF data extension %s in %s",
+                imageName, file->filename);
+        return false;
     }
 
     header = psFitsReadHeader (NULL, file->fits);
+    if (!header) {
+        psError(psErrorCodeLast(), false, "Unable to read PSF header.");
+        return false;
+    }
     int Naxis = psMetadataLookupS32 (&status, header, "NAXIS");
     if (Naxis != 0) {
@@ -936,9 +1013,18 @@
 
         psRegion fullImage = {0, 0, 0, 0};
-        psFitsReadImageBuffer(psf->residuals->Ro, file->fits, fullImage, 0); // Desired pixels
+        if (!psFitsReadImageBuffer(psf->residuals->Ro, file->fits, fullImage, 0)) {
+            psError(psErrorCodeLast(), false, "Unable to read PSF residual image.");
+            return false;
+        }
         if (Nz > 1) {
             assert (Nz == 3);
-            psFitsReadImageBuffer(psf->residuals->Rx, file->fits, fullImage, 1); // Desired pixels
-            psFitsReadImageBuffer(psf->residuals->Ry, file->fits, fullImage, 2); // Desired pixels
+            if (!psFitsReadImageBuffer(psf->residuals->Rx, file->fits, fullImage, 1)) {
+                psError(psErrorCodeLast(), false, "Unable to read PSF residual image.");
+                return false;
+            }
+            if (!psFitsReadImageBuffer(psf->residuals->Ry, file->fits, fullImage, 2)) {
+                psError(psErrorCodeLast(), false, "Unable to read PSF residual image.");
+                return false;
+            }
         }
         // XXX notice that we are not saving the resid->mask
Index: /trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c	(revision 27176)
+++ /trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c	(revision 27177)
@@ -216,5 +216,10 @@
 
     if (table->n == 0) {
-        psFitsWriteBlank(fits, header, extname);
+        if (!psFitsWriteBlank(fits, header, extname)) {
+            psError(psErrorCodeLast(), false, "Unable to write empty sources file.");
+            psFree(table);
+            psFree(header);
+            return false;
+        }
         psFree(table);
         psFree(header);
@@ -224,5 +229,5 @@
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable(fits, header, table, extname)) {
-        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
         psFree(table);
         psFree(header);
@@ -486,5 +491,10 @@
 
     if (table->n == 0) {
-        psFitsWriteBlank (fits, outhead, extname);
+        if (!psFitsWriteBlank (fits, outhead, extname)) {
+            psError(psErrorCodeLast(), false, "Unable to write empty sources.");
+            psFree(outhead);
+            psFree(table);
+            return false;
+        }
         psFree (outhead);
         psFree (table);
@@ -494,5 +504,5 @@
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable (fits, outhead, table, extname)) {
-        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
         psFree (outhead);
         psFree(table);
@@ -612,5 +622,10 @@
 
     if (table->n == 0) {
-        psFitsWriteBlank (fits, outhead, extname);
+        if (!psFitsWriteBlank (fits, outhead, extname)) {
+            psError(psErrorCodeLast(), false, "Unable to write empty sources.");
+            psFree(outhead);
+            psFree(table);
+            return false;
+        }
         psFree (outhead);
         psFree (table);
@@ -620,5 +635,5 @@
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable (fits, outhead, table, extname)) {
-        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
         psFree (outhead);
         psFree(table);
Index: /trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V2.c
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V2.c	(revision 27176)
+++ /trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V2.c	(revision 27177)
@@ -216,5 +216,10 @@
 
     if (table->n == 0) {
-        psFitsWriteBlank(fits, header, extname);
+        if (!psFitsWriteBlank(fits, header, extname)) {
+            psError(psErrorCodeLast(), false, "Unable to write blank sources file.");
+            psFree(table);
+            psFree(header);
+            return false;
+        }
         psFree(table);
         psFree(header);
@@ -224,5 +229,5 @@
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable(fits, header, table, extname)) {
-        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
         psFree(table);
         psFree(header);
@@ -264,4 +269,9 @@
     for (int i = 0; i < numSources; i++) {
         psMetadata *row = psFitsReadTableRow(fits, i); // Table row
+        if (!row) {
+            psError(psErrorCodeLast(), false, "Unable to read row %d of sources", i);
+            psFree(sources);
+            return NULL;
+        }
 
         pmSource *source = pmSourceAlloc ();
@@ -487,5 +497,10 @@
 
     if (table->n == 0) {
-        psFitsWriteBlank (fits, outhead, extname);
+        if (!psFitsWriteBlank (fits, outhead, extname)) {
+            psError(psErrorCodeLast(), false, "Unable to write empty sources file.");
+            psFree(outhead);
+            psFree(table);
+            return false;
+        }
         psFree (outhead);
         psFree (table);
@@ -495,5 +510,5 @@
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable (fits, outhead, table, extname)) {
-        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
         psFree (outhead);
         psFree(table);
@@ -613,5 +628,10 @@
 
     if (table->n == 0) {
-        psFitsWriteBlank (fits, outhead, extname);
+        if (!psFitsWriteBlank (fits, outhead, extname)) {
+            psError(psErrorCodeLast(), false, "Unable to write empty sources file.");
+            psFree(outhead);
+            psFree(table);
+            return false;
+        }
         psFree (outhead);
         psFree (table);
@@ -621,5 +641,5 @@
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable (fits, outhead, table, extname)) {
-        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
         psFree (outhead);
         psFree(table);
Index: /trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c	(revision 27176)
+++ /trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c	(revision 27177)
@@ -67,83 +67,83 @@
 
     if (!table) {
-	table = psArrayAllocEmpty (0x1000);
-	pmFPAview *view = pmFPAviewAlloc (0);
+        table = psArrayAllocEmpty (0x1000);
+        pmFPAview *view = pmFPAviewAlloc (0);
 
-	// this loop selects the matched stars for all chips
-	while ((chip = pmFPAviewNextChip (view, fpa, 1)) != NULL) {
-	    psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
-	    if (!chip->process || !chip->file_exists) continue;
+        // this loop selects the matched stars for all chips
+        while ((chip = pmFPAviewNextChip (view, fpa, 1)) != NULL) {
+            psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+            if (!chip->process || !chip->file_exists) continue;
 
-	    char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
+            char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
 
-	    while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
-		psTrace ("psastro", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
-		if (!cell->process || !cell->file_exists) continue;
+            while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
+                psTrace ("psastro", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+                if (!cell->process || !cell->file_exists) continue;
 
-		// process each of the readouts
-		// XXX there can only be one readout per chip, right?
-		while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {
-		    if (! readout->data_exists) continue;
+                // process each of the readouts
+                // XXX there can only be one readout per chip, right?
+                while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {
+                    if (! readout->data_exists) continue;
 
-		    // select the raw objects for this readout
-		    psArray *rawstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.RAWSTARS");
-		    if (rawstars == NULL) continue;
+                    // select the raw objects for this readout
+                    psArray *rawstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.RAWSTARS");
+                    if (rawstars == NULL) continue;
 
-		    // select the raw objects for this readout
-		    psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS");
-		    if (refstars == NULL) continue;
-		    psTrace ("psastro", 4, "Trying %ld refstars\n", refstars->n);
+                    // select the raw objects for this readout
+                    psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS");
+                    if (refstars == NULL) continue;
+                    psTrace ("psastro", 4, "Trying %ld refstars\n", refstars->n);
 
 # if (0)
-		    // XXX test
-		    FILE *outfile = fopen ("refstars.dat", "w");
-		    assert (outfile);
-		    for (int nn = 0; nn < refstars->n; nn++) {
-			pmAstromObj *ref = refstars->data[nn];
-			fprintf (outfile, "%lf %lf\n", ref->sky->r*PS_DEG_RAD, ref->sky->d*PS_DEG_RAD);
-		    }
-		    fclose (outfile);
+                    // XXX test
+                    FILE *outfile = fopen ("refstars.dat", "w");
+                    assert (outfile);
+                    for (int nn = 0; nn < refstars->n; nn++) {
+                        pmAstromObj *ref = refstars->data[nn];
+                        fprintf (outfile, "%lf %lf\n", ref->sky->r*PS_DEG_RAD, ref->sky->d*PS_DEG_RAD);
+                    }
+                    fclose (outfile);
 # endif
 
-		    psArray *matches = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.MATCH");
-		    if (matches == NULL) continue;
+                    psArray *matches = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.MATCH");
+                    if (matches == NULL) continue;
 
-		    for (int i = 0; i < matches->n; i++) {
-			pmAstromMatch *match = matches->data[i];
+                    for (int i = 0; i < matches->n; i++) {
+                        pmAstromMatch *match = matches->data[i];
 
-			pmAstromObj *raw = rawstars->data[match->raw];
-			pmAstromObj *ref = refstars->data[match->ref];
+                        pmAstromObj *raw = rawstars->data[match->raw];
+                        pmAstromObj *ref = refstars->data[match->ref];
 
-			psMetadata *row = psMetadataAlloc ();
-			psMetadataAdd (row, PS_LIST_TAIL, "RA",       PS_DATA_F64, "right ascension (deg, J2000)", PM_DEG_RAD*ref->sky->r);
-			psMetadataAdd (row, PS_LIST_TAIL, "DEC",      PS_DATA_F64, "declination (deg, J2000)",     PM_DEG_RAD*ref->sky->d);
-			psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP",   PS_DATA_F32, "x coord on chip",              raw->chip->x);
-			psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP",   PS_DATA_F32, "y coord on chip",              raw->chip->y);
-			psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP_FIT",PS_DATA_F32, "x fitted coord on chip",      ref->chip->x);
-			psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP_FIT",PS_DATA_F32, "y fitted coord on chip",      ref->chip->y);
-			psMetadataAdd (row, PS_LIST_TAIL, "X_FPA",    PS_DATA_F32, "x coord on focal plane",       raw->FP->x);
-			psMetadataAdd (row, PS_LIST_TAIL, "Y_FPA",    PS_DATA_F32, "y coord on focal plane",       raw->FP->y);
-			psMetadataAdd (row, PS_LIST_TAIL, "MAG_INST", PS_DATA_F32, "instrumental magnitude",       raw->Mag);
-			psMetadataAdd (row, PS_LIST_TAIL, "MAG_REF",  PS_DATA_F32, "reference star magnitude",     ref->Mag);
-			psMetadataAdd (row, PS_LIST_TAIL, "COLOR_REF",PS_DATA_F32, "reference star color",         ref->Color);
-			psMetadataAdd (row, PS_LIST_TAIL, "CHIP_ID",  PS_DATA_STRING, "chip identifier",           chipName);
-			// XXX need to add the reference color, but this needs getstar / dvo.photcodes for the reference to be refined.
+                        psMetadata *row = psMetadataAlloc ();
+                        psMetadataAdd (row, PS_LIST_TAIL, "RA",       PS_DATA_F64, "right ascension (deg, J2000)", PM_DEG_RAD*ref->sky->r);
+                        psMetadataAdd (row, PS_LIST_TAIL, "DEC",      PS_DATA_F64, "declination (deg, J2000)",     PM_DEG_RAD*ref->sky->d);
+                        psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP",   PS_DATA_F32, "x coord on chip",              raw->chip->x);
+                        psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP",   PS_DATA_F32, "y coord on chip",              raw->chip->y);
+                        psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP_FIT",PS_DATA_F32, "x fitted coord on chip",      ref->chip->x);
+                        psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP_FIT",PS_DATA_F32, "y fitted coord on chip",      ref->chip->y);
+                        psMetadataAdd (row, PS_LIST_TAIL, "X_FPA",    PS_DATA_F32, "x coord on focal plane",       raw->FP->x);
+                        psMetadataAdd (row, PS_LIST_TAIL, "Y_FPA",    PS_DATA_F32, "y coord on focal plane",       raw->FP->y);
+                        psMetadataAdd (row, PS_LIST_TAIL, "MAG_INST", PS_DATA_F32, "instrumental magnitude",       raw->Mag);
+                        psMetadataAdd (row, PS_LIST_TAIL, "MAG_REF",  PS_DATA_F32, "reference star magnitude",     ref->Mag);
+                        psMetadataAdd (row, PS_LIST_TAIL, "COLOR_REF",PS_DATA_F32, "reference star color",         ref->Color);
+                        psMetadataAdd (row, PS_LIST_TAIL, "CHIP_ID",  PS_DATA_STRING, "chip identifier",           chipName);
+                        // XXX need to add the reference color, but this needs getstar / dvo.photcodes for the reference to be refined.
 
-			psArrayAdd (table, 100, row);
-			psFree (row);
-		    }
-		}
-	    }
-	}
-	psFree (view);
+                        psArrayAdd (table, 100, row);
+                        psFree (row);
+                    }
+                }
+            }
+        }
+        psFree (view);
 
-	if (table->n == 0) {
-	    psFree(table);
-	    return true;
-	}
+        if (table->n == 0) {
+            psFree(table);
+            return true;
+        }
     }
 
     if (!psFitsWriteTable(fits, NULL, table, "MATCHED_REFS")) {
-        psError(PS_ERR_IO, false, "writing MATCHED_REFS\n");
+        psError(psErrorCodeLast(), false, "writing MATCHED_REFS\n");
         psFree(table);
         return false;
@@ -165,8 +165,8 @@
     // It is not an error to lack this entry -- psFitsMoveExtNameClean does not raise an error
     if (!psFitsMoveExtNameClean (fits, "MATCHED_REFS")) {
-	psMetadataAddBool (fpa->analysis, PS_LIST_TAIL, "READ.REFMATCH", PS_META_REPLACE, "attempted to read MATCHED_REFS", true);
-	return true;
+        psMetadataAddBool (fpa->analysis, PS_LIST_TAIL, "READ.REFMATCH", PS_META_REPLACE, "attempted to read MATCHED_REFS", true);
+        return true;
     }
-    
+
     // We get the size of the table, and allocate the array of sources first because the table
     // is large and ephemeral --- when the table gets blown away, whatever is allocated after
@@ -178,5 +178,10 @@
     for (int i = 0; i < numRows; i++) {
         psMetadata *row = psFitsReadTableRow(fits, i); // Table row
-	rows->data[i] = row;
+        if (!row) {
+            psError(psErrorCodeLast(), false, "Unable to read row %d of matched references.", i);
+            psFree(rows);
+            return false;
+        }
+        rows->data[i] = row;
     }
 
